home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / go630.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  125.9 KB  |  6,550 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create:
  6. #    README
  7. #    games
  8. #    src
  9. # This archive created: Wed Feb 21 22:52:27 1990
  10. export PATH; PATH=/bin:/usr/bin:$PATH
  11. if test -f 'README'
  12. then
  13.     echo shar: "will not over-write existing file 'README'"
  14. else
  15. cat << \SHAR_EOF > 'README'
  16. To print documentation :-
  17.     mmx -t -gc $GO/src/go.mmx
  18. or if there is no memorandum macro formatter :-
  19.     lp $GO/src/go.mmx.out
  20. SHAR_EOF
  21. fi
  22. if test ! -d 'games'
  23. then
  24.     mkdir 'games'
  25. fi
  26. cd 'games'
  27. if test -f 'basics.go'
  28. then
  29.     echo shar: "will not over-write existing file 'basics.go'"
  30. else
  31. cat << \SHAR_EOF > 'basics.go'
  32. #"basics.go" - press space now and everytime you wish to see more lines
  33. !numbers
  34. !lastmove
  35. 9 0|
  36. #Go can can be played on any size board though 9x9, 13x13 and 19x19
  37. #are more usual. For the moment we shall use a 9x9 board.
  38. #Play starts with the board empty.
  39. #A move consists of placing a piece (called a 'stone') on a vacant point, any
  40. #vacant point can be chosen, subject to a prohibition described later.
  41. #Players move alternately, Black moving first eg at D3
  42. d3 |
  43. # ... then white at C7
  44. C7 |
  45. # and black at C5
  46. C5 |
  47. # and so on.
  48. #                                    |
  49. #Stones once played are not moved about, unless they are captured, in which 
  50. #case they are removed from the board.
  51. #Thus the board gradually fills up with stones during play.
  52. #                                    |
  53. #The basic object of the game is to surround vacant areas of the board.
  54. #the player who controls more territory, consisting of vacant points, at 
  55. #the end of the game is the winner.
  56. #For example here is a game that has been completed ...
  57.  
  58. 9 0    |
  59. B9    |
  60. pass    |
  61. B8    |
  62. pass    |
  63. C8    |
  64. pass    |
  65. C7    |
  66. pass    |
  67. D7    |
  68. pass    |
  69. D6    |
  70. pass    |
  71. D5    |
  72. pass    |
  73. E5    |
  74. pass    |
  75. F5    |
  76. pass    |
  77. G5    |
  78. pass    |
  79. F6    |
  80. pass    |
  81. F7    |
  82. pass    |
  83. E8    |
  84. pass    |
  85. E9    |
  86. pass    |
  87. F9    |
  88. pass    |
  89. F4    |
  90. pass    |
  91. F3    |
  92. pass    |
  93. F2    |
  94. pass    |
  95. E1    |
  96. pass    |
  97. D2    |
  98. pass    |
  99. D3    |
  100. E2    |
  101. E3    |
  102. pass    |
  103. H4    |
  104. pass    |
  105. H3    |
  106. pass    |
  107. J3    |
  108. A9    |
  109. pass    |
  110. A8    |
  111. pass    |
  112. A7    |
  113. pass    |
  114. B7    |
  115. pass    |
  116. B6    |
  117. pass    |
  118. C6    |
  119. pass    |
  120. C5    |
  121. pass    |
  122. C4    |
  123. pass    |
  124. D4    |
  125. pass    |
  126. E4    |
  127. pass    |
  128. C3    |
  129. pass    |
  130. C2    |
  131. pass    |
  132. C1    |
  133. pass    |
  134. D1    |
  135. pass    |
  136. F8    |
  137. pass    |
  138. G9    |
  139. pass    |
  140. G8    |
  141. pass    |
  142. G7    |
  143. pass    |
  144. G6    |
  145. pass    |
  146. H6    |
  147. pass    |
  148. H5    |
  149. pass    |
  150. J5    |
  151. pass    |
  152. J4    |
  153. pass    |
  154. J7    |
  155.  
  156. #Black has surrounded 15 vacant points (10 in the lower right corner and 5
  157. #towards the top of the board), and white has 17 (11 in the lower left corner
  158. #and 6 in the upper right corner)
  159. #                                    |
  160. #Players also score a point for each enemy stone they capture during the game.
  161. #In this game Black captured one prisoner stone, so his total score was 16.
  162. #White captured no stones but still won by one point.
  163. #                                    |
  164. #It is not worth either player playing on any of the remaining vacant points
  165. #because any stones played would eventually be captured as there is no way
  166. #to make stones thus played into "invulnerable groups" (see later).
  167. #                                    |
  168. #The game ends by mutual agreement, because both players can see that further
  169. #moves cannot benefit either of them.
  170. #                                    |
  171. #Beginners who are in any doubt whether a game is finished are advised to
  172. #continue playing until the issue is quite clear to both players.
  173. #                                    |
  174. #To demonstrate the way to capture stones in Go we shall now move on to a 13x13
  175. #board, note that the following situations are only to illustrate the rules of
  176. #Go and are unlikely to occur in a real game.
  177. 13 0|
  178.  
  179. e8#The stone at e8 has four 'freedoms' at e9, f8, e7 and d8, when all it's
  180. #freedoms are occupied by opponents' stones then it will be captured.
  181. e9|
  182. pass|
  183. f8|
  184. pass|
  185. e7|
  186. pass|
  187. #e8 is now in 'atari' (which means "threat to capture" in Japanese), ie it has
  188. #only one freedom left, all that is required is for white to play at d8 and it
  189. #will be captured.
  190. d8|
  191. #                                    |
  192. #Stones of the same colour can be connected into groups. The connections can
  193. #only be up, down or left, right but not diagonally.
  194. #                                    |
  195. j7|
  196. pass|
  197. j6|
  198. #This two stone group has six freedoms at j8, k7, k6, j5, h6 and h7. 
  199. #White surrounds all but one of its freedoms ...
  200. j8|
  201. pass|
  202. k7|
  203. pass|
  204. k6|
  205. pass|
  206. h7|
  207. pass|
  208. h6|
  209. #If black ignores this atari (threat to capture) by playing elsewhere
  210. #and white plays at j5 then the group will be removed.
  211. pass|
  212. j5
  213. #                                    |
  214. #Groups against the sides and corners have correspondingly less freedoms ...
  215. A13|
  216. pass|
  217. b13|
  218. #This black group (A13, B13) has only 3 freedoms.
  219. #                                    |
  220. #Another example ...
  221. pass|
  222. d1|
  223. c1|
  224. d2|
  225. c2|
  226. d3|
  227. c3|
  228. e3|
  229. d4|
  230. f4|
  231. e4|
  232. g4|
  233. e2|
  234. pass|
  235. e1|
  236. pass|
  237. f2|
  238. pass|
  239. g2|
  240. #Here are TWO black groups (the diagonal between E3-F3 means they are separated)
  241. #if it is white's move then playing at f3 will kill the four stone black
  242. #group, if it is black to play then f3 would connect the two groups ...
  243. f3|
  244. # ... giving it (the single black group) four freedoms (f5, g5, h4, g3).
  245. #                                    |
  246. #It is illegal to play a stone in such a place that it will have no freedoms,
  247. #ie black cannot play at e8 as this is a "suicidal" move. If however the
  248. #situation was as follows ...
  249. pass|
  250. d9|
  251. pass|
  252. c8|
  253. pass|
  254. d7|
  255. pass|
  256. # ... then black may play at e8 because in playing there it removes the white
  257. #stone at d8, thus giving it (the black stone) one freedom.
  258. e8|
  259. #                                    |
  260. #White cannot play immediately back in d8. This situation is called a 'ko'
  261. #Ko in  Japanese means eternity and the rule of Ko forbids a "tit for tat"
  262. #infinite exchange. White must play elsewhere, hoping that black will answer
  263. #the move and then white can play back in d8, then black will have to find
  264. #a move that white will have to answer and so on. An example of a Ko battle is 
  265. #explained more in "kobattle.go".
  266. 13 0|
  267. #Being unable to make suicidal move leads to the formation of "invulnerable 
  268. #groups", for example ...
  269. m1|
  270. j1|
  271. k1|
  272. j2|
  273. k2|
  274. k3|
  275. l2|
  276. l3|
  277. m2|
  278. m3|
  279. n2|
  280. n3|
  281. #                                    |
  282. #It is white's move but is unable to capture the black group in the corner
  283. #because it has 'two eyes' - white cannot play at L1 because the black 
  284. #group has still one freedom at N1, thus this would be a suicidal (illegal)
  285. #move.
  286. #                                    |
  287. #In the completed game shown earlier it would not be possible for a player
  288. #to invade the opponent's territory because there would be no room for the
  289. #"invader" to make two eyes so eventually the invaders' stones would be captured
  290. #When both players realise there is no point in playing in the remaining vacant
  291. #points on the board the game ends.
  292. #                                    |
  293. #Go back to line 124 (with ^N), this will take you to the end of the completed
  294. #game shown earlier, use practice mode to satisfy yourself there is no room to
  295. #live in the remaining places (it is black to move next). To return to here,
  296. #goto line 262.
  297. #                                    |
  298. #At the end of the game there may be remnants of groups abandoned (for example
  299. #in "example.go") it is not necessary to play these out, they are just treated
  300. #as captured when it comes to counting up at the end.
  301. SHAR_EOF
  302. fi
  303. if test -f 'bgj.75.go'
  304. then
  305.     echo shar: "will not over-write existing file 'bgj.75.go'"
  306. else
  307. cat << \SHAR_EOF > 'bgj.75.go'
  308. 19 0 # Tudball (8) vs. Rudd (9)
  309. c4
  310. q3
  311. q16
  312. d17
  313. e4
  314. r14
  315. d15 #An excellent move, approaching White 4 (d17) while developing in  front of
  316.    #the shimari. Because of this, white should have prefered to play 6 (r14)
  317.    #at d15, c15 or c14.
  318. c15
  319. c14
  320. c16
  321. d13
  322. c9 #If white had played at f17, to complete the joseki, then black would have 
  323.   #played on the left side getting good shape in relation to 1 and 5 (d4) (e4)
  324.   #However this just gives black a target to aim at, other approaches to 
  325.   #consider are :-
  326.   #(a) Complete the joseki and take sente to play elsewhere, worrying less 
  327.   #about blacks's postion and doing more about white's own.
  328.   #(b) Use 8 (c15) to play a pincer immediately, without committing yourself to
  329.   #one shape in the corner.
  330.   #(c) Play 12 (c9) on the fourth line, for an easier escape into the centre.
  331. e9 #Black choses to confine white on the left side, still hoping to keep sente
  332.    #and return to the vicinty of 4 (17) later.
  333. c12
  334. b14
  335. b15 #At this stage it is more important to get the corner group out into the
  336.     #open at (f17) than to protect a few points of corner territory. But the
  337.     #corner group cannot be killed yet, so a jump out to e11 would be better
  338.     #still, moving out and separating black as well.
  339. d11
  340. b12
  341. d12
  342. f17
  343. #The left hand white group is very weak, it's ok to play elsewhere if it is
  344. #for something bigger, however there isn't anything bigger and both sides should
  345. #be eager to play here.
  346. O16
  347. R11
  348. R5
  349. R8
  350. #Trying to use R11 (22) to help attack.
  351. P5
  352. O3
  353. #Should be one position higher at O4 because of the strength of R8 and R11
  354. S3
  355. L3
  356. H3
  357. K5
  358. R2
  359. Q2
  360. N4
  361. M3
  362. N3
  363. N2
  364. O4
  365. P3
  366. Q7
  367. E14
  368. E15
  369. F15
  370. D14
  371. G14
  372. K16
  373. J17
  374. K17
  375. J18
  376. K18
  377. R17
  378. R16
  379. Q17
  380. P17
  381. S16
  382. S15
  383. T16
  384. R15
  385. S14
  386. T15
  387. S18
  388. Q18
  389. R18
  390. J16
  391. H17
  392. J14
  393. M15
  394. M16
  395. O14
  396. N15
  397. P15
  398. O15
  399. P14
  400. P16
  401. O9
  402. Q10
  403. R10
  404. P9
  405. Q11
  406. P11
  407. P12
  408. O11
  409. C6
  410. C10#This should have been a lot earlier, why wait to attack after white has
  411.    #strenghtened the left side at d6 ?
  412. B10
  413. B11
  414. B9
  415. C11
  416. A11
  417. D7
  418. C7
  419. D6
  420. S6
  421. S5
  422. R7
  423. R6
  424. B5
  425. B4
  426. G5
  427. H5
  428. H4
  429. G4
  430. J4
  431. H6
  432. G3
  433. F4
  434. G2
  435. F2
  436. F3
  437. E2
  438. J3
  439. J9
  440. G12
  441. F13
  442. G13
  443. F14
  444. F12
  445. E13
  446. F16
  447. N9
  448. P8
  449. Q8
  450. M6
  451. N7
  452. E10
  453. E11
  454. E8
  455. D8
  456. D10
  457. D9
  458. F11
  459. F10
  460. J7
  461. H7
  462. J8
  463. H8
  464. K9
  465. O12
  466. O13
  467. L6
  468. L7
  469. L5
  470. M5
  471. K10
  472. L9
  473. L10
  474. H9
  475. J10
  476. G10
  477. G9
  478. H10
  479. F8
  480. N10
  481. O10
  482. M9
  483. N8
  484. N11
  485. M10
  486. N12
  487. O8
  488. J12
  489. K12
  490. J13
  491. K13
  492. K11
  493. J11
  494. L11
  495. H12
  496. H13
  497. G11
  498. H11
  499. M14
  500. P18
  501. O18
  502. Q19
  503. R9
  504. S9
  505. Q9
  506. S8
  507. C5
  508. B6
  509. C8
  510. B8
  511. H16
  512. G16
  513. Q14
  514. Q13
  515. Q15
  516. S13
  517. SHAR_EOF
  518. fi
  519. cd ..
  520. if test ! -d 'src'
  521. then
  522.     mkdir 'src'
  523. fi
  524. cd 'src'
  525. if test -f 'c'
  526. then
  527.     echo shar: "will not over-write existing file 'c'"
  528. else
  529. cat << \SHAR_EOF > 'c'
  530. case $TERM in
  531.  
  532.     630)    dmdcc -g -ogo.630.out go.c go.630.c -Ddmd ;\
  533.         mv go.630.out $GO/bin ;;
  534.  
  535.     *)    make ;;
  536.  
  537. esac
  538. SHAR_EOF
  539. fi
  540. if test -f 'go.630.c'
  541. then
  542.     echo shar: "will not over-write existing file 'go.630.c'"
  543. else
  544. cat << \SHAR_EOF > 'go.630.c'
  545. #include <dmd.h>
  546. #include <object.h>
  547.  
  548. #include "go.h"
  549. #include "go.extern.h"
  550.  
  551. #define byte unsigned short
  552.  
  553. #include <font.h>
  554. short jwidths() ;
  555. short jputs() ;
  556. byte jputc() ;
  557. char initjput() ;
  558.  
  559. #include "go_icon"
  560.  
  561. #include "null_icon"
  562. #include "tick_icon"
  563. Bitmap bm_tick = { (Word *)tick_icon, 1, 0, 0, 15, 15, 0, } ;
  564. Bitmap bm_null = { (Word *)null_icon, 1, 0, 0, 15, 15, 0, } ;
  565.  
  566.  
  567. #define LEDGE 60    /* distance from top and left of board to window edge */
  568. #define GRIDSIZE 44    /* distance between the lines on the board */
  569. #define STONERADIUS 17
  570.  
  571. #define GAP (GRIDSIZE-(STONERADIUS*2)) /* gap between neighbouring stones */
  572.  
  573. /* the left hand edge of any text displayed */
  574. #define XSTARTPOS 20
  575.  
  576. /* key definitions */
  577. #define BACKSPACE 8
  578. #define KILLLINE 127
  579. #define RETURN 13 /* this is carriage return on the keyboard ^M, ('\n' is ^J) */
  580.  
  581. /* Variables Global to this file */
  582. short lastwidth ;    /* width of last lastmove string */
  583. int promptline ;    /* position to write the next line of text */
  584. int linedisplayed ;    /* number of lines displayed */
  585.  
  586. BOOLEAN buttonpressedlasttime ;
  587.  
  588. int HEDGE ;    /* distance between right and bottom of board to the window edge*/
  589. char fontheight ;    /* Height of the font */
  590.  
  591.  
  592. char dsize ; /* Used between downsize() and getinput() */
  593. MOVENUMBER hgoto; /* Used between hitgoto() and getinput() */
  594. char dgoto ; /* set by downgoto(), read by gotogenerator() and getinput() */
  595.  
  596. /****************************************************************************/
  597. /*           Menu variables                                                 */
  598. /****************************************************************************/
  599. #include <menu.h>
  600. void downsize() ;
  601. void downgoto() ;
  602. void hitgoto() ;
  603.  
  604. #define size9 (spacebar+1)    /* assumes spacebar is the last ACTIONTYPE */
  605. #define size13 (spacebar+2)
  606. #define size19 (spacebar+3)
  607.  
  608. #define GOTOMOVE 0
  609. #define GOTOLINE 1
  610.  
  611. Titem *gotogenerator() ;
  612. extern Tmenu menu00, menu10, menu11, menu12, menu20, menu21, menu22, menu30 ;
  613.  
  614. typedef struct ROOTMENU
  615. {
  616.     char *text ;
  617.     struct {
  618.         Word uval ;
  619.         Word grey ;
  620.         } ufield ;
  621.     struct Tmenu *next ;
  622.     Bitmap *icon ;
  623. } ROOTMENU ;
  624.  
  625. typedef struct CONFIGMENU
  626. {
  627.     char *text ;
  628.     struct {
  629.         Word uval ;
  630.         Word grey ;
  631.         } ufield ;
  632.     struct Tmenu *next ;
  633.     Bitmap *icon ;
  634. } CONFIGMENU ;
  635.  
  636. typedef struct GOTOMENU
  637. {
  638.     char *text ;
  639.     struct {
  640.         Word uval ;
  641.         Word grey ;
  642.         } ufield ;
  643.     struct Tmenu *next ;
  644.     void (*dfn)() ;
  645. } GOTOMENU ;
  646.  
  647. typedef struct SIZEMENU
  648. {
  649.     char *text ;
  650.     struct {
  651.         Word uval ;
  652.         Word grey ;
  653.         } ufield ;
  654.     struct Tmenu *next ;
  655.     void (*dfn)() ;
  656. } SIZEMENU ;
  657.  
  658. typedef struct HANDICAPMENU
  659. {
  660.     char *text ;
  661.     struct {
  662.         Word uval ;
  663.         Word grey ;
  664.         } ufield ;
  665. } HANDICAPMENU ;
  666.  
  667. typedef struct VERSIONMENU
  668. {
  669.     char *text ;
  670. } VERSIONMENU ;
  671.  
  672. ROOTMENU rootmenu[] =
  673. {
  674.     "practice",(Word)practice,0,0,0,
  675.     "step through",(Word)stepthrough,0,0,0,
  676.     "read from",(Word)readfrom,0,0,0,
  677.     "undo",(Word)undo,0,0,0,
  678.     "configure",0,0,&menu10,0,
  679.     "pass", (Word)pass,0,0,0,
  680.     "write to",(Word)writeto,0,0,0,
  681.     "version",0,0,&menu11,0,
  682.     "redraw",(Word)redraw,0,0,0,
  683.     "cd",(Word)cd,0,0,0,
  684.     "goto",0,0,&menu12,0,
  685.     "quit", (Word)quit,0,0,0,
  686.     0
  687. };
  688.  
  689. CONFIGMENU configmenu[] =
  690. {
  691.     "numbers",(Word)numbers,0,0,0,
  692.     "grid",(Word)grid,0,0,0,
  693.     "last move",(Word)lastmove,0,0,0,
  694.     "size",0,0,&menu20,0,
  695.     0
  696. };
  697.  
  698. GOTOMENU gotomenu[] =
  699. {
  700.     "move",GOTOMOVE,0,&menu21,downgoto,
  701.     "line",GOTOLINE,0,&menu22,downgoto,
  702.     0
  703. } ;
  704.  
  705. SIZEMENU sizemenu[] =
  706. {
  707.     "9", (Word)size9,0,&menu30,downsize,
  708.     "13",(Word)size13,0,&menu30,downsize,
  709.     "19",(Word)size19,0,&menu30,downsize,
  710.     0
  711. };
  712.  
  713. HANDICAPMENU handicapmenu[] =
  714. {
  715.     "0", (Word)changehandicap,0,
  716.     "2", (Word)changehandicap,0,
  717.     "3", (Word)changehandicap,0,
  718.     "4", (Word)changehandicap,0,
  719.     "5", (Word)changehandicap,0,
  720.     "6", (Word)changehandicap,0,
  721.     "7", (Word)changehandicap,0,
  722.     "8", (Word)changehandicap,0,
  723.     "9", (Word)changehandicap,0,
  724.     0
  725. } ;
  726.  
  727. VERSIONMENU versionmenu[] =
  728. {
  729.     version,
  730.     0
  731. } ;
  732.  
  733. Tmenu menu00 = { (Titem *)rootmenu,0, 0, 0, TM_TEXT|TM_NEXT|TM_UFIELD|TM_ICON } ;
  734. Tmenu menu10 = { (Titem *)configmenu,0, 0, 0, TM_TEXT|TM_NEXT|TM_ICON|TM_UFIELD } ;
  735. Tmenu menu11 = { (Titem *)versionmenu,0, 0, 0, TM_TEXT} ;
  736. Tmenu menu12 = { (Titem *)gotomenu,0,0,0,TM_TEXT|TM_UFIELD|TM_NEXT|TM_DFN } ;
  737. Tmenu menu21 = { (Titem *)0,0,0,gotogenerator,0 } ;
  738. Tmenu menu22 = { (Titem *)0,0,0,gotogenerator,0 } ;
  739. Tmenu menu20 = { (Titem *)sizemenu,0, 0, 0, TM_TEXT|TM_UFIELD|TM_DFN|TM_NEXT} ;
  740. Tmenu menu30 = { (Titem *)handicapmenu,0, 0, 0, TM_TEXT|TM_UFIELD };
  741. /*****************************************************************************/
  742.  
  743. /*
  744.  * Function:    errorprint
  745.  *        
  746.  * Description:    Displays the string passed as an error message.
  747.  *        
  748.  * Globals affected:    none
  749.  *            
  750.  */
  751. void
  752. errorprint(s)
  753. char *s ;
  754. {
  755.     Lprintf("%s",s) ;
  756.     Lprintf(" ... hit any key to continue") ;
  757.     do
  758.         wait(KBD) ;
  759.     while ( kbdchar()==(-1) ) ;
  760. }
  761.  
  762. /*
  763.  * Function:    displaylastmove
  764.  *        
  765.  * Description:    If the last move flag is set, display the string passed.
  766.  *        
  767.  *        
  768.  * Globals affected:    none
  769.  *            
  770.  */
  771. void
  772. displaylastmove(str)
  773. char str[] ;
  774. {
  775. short  w ;
  776.  
  777.  
  778.     if (flag[LASTMOVE]==on)
  779.     {
  780.         jrectf( Rpt(Pt(HEDGE+GRIDSIZE*2-(lastwidth/2),
  781.                    LEDGE+GRIDSIZE*5-(fontheight/2)),
  782.                 Pt(HEDGE+GRIDSIZE*2+(lastwidth/2),
  783.                    LEDGE+GRIDSIZE*5+(fontheight/2)) ),
  784.                 F_CLR ) ;
  785.     
  786.         w = jwidths(str) ;
  787.  
  788.         (void)jputs( Pt(HEDGE+GRIDSIZE*2-(w/2),
  789.                 LEDGE+GRIDSIZE*5-(fontheight/2)),
  790.                  str,
  791.                  F_STORE) ;
  792.     
  793.         lastwidth = w ;
  794.     }
  795. }
  796.  
  797. /*
  798.  * Function:    erasescreen()
  799.  *        
  800.  * Description:    Clears the  whole of the window.
  801.  *        
  802.  * Globals affected:    none
  803.  *            
  804.  */
  805. erasescreen()
  806. {
  807.     jrectf ( Rpt(Pt(0,0),Pt(XMAX-1,YMAX-1)), F_CLR ) ;
  808. }
  809.  
  810. /*
  811.  * Function:    reconfigure
  812.  *        
  813.  * Description:    The size of the board has changed, set variables accordingly.
  814.  *        
  815.  *        
  816.  * Globals affected:    HEDGE, promptline
  817.  *            
  818.  */
  819. reconfigure()
  820. {
  821. char i ;
  822.  
  823.     HEDGE = ( size - 1 ) * GRIDSIZE + LEDGE ;
  824.  
  825.     promptline = HEDGE + STONERADIUS + fontheight ;
  826.  
  827. }
  828.  
  829. /*
  830.  * Function:    getinput()
  831.  *        
  832.  * Description:    Gets input from keyboard or mouse.
  833.  *        Sets action to be one of the following, with corresponding
  834.  *        data in the buffer.
  835.  *        Any strings returned in the buffer always end with a newline
  836.  *        and a null.
  837.  *
  838.  *        action        actbuffer
  839.  *        ------        ---------
  840.  *        cd        null
  841.  *        gotomove    Decimal byte string "1" to "999", ending with
  842.  *                newline. Maximum of four bytes long, plus '\0'.
  843.  *        gotoline    decimal string "1" to "999" ending with newline.
  844.  *                Maximum of four bytes long, plus '\0'.
  845.  *        changehandicap    first byte is size, second is handicap
  846.  *        numbers        null
  847.  *        pass        null
  848.  *        practice    null
  849.  *        quit        null
  850.  *        rawkeyboard    string typed in from the keyboard
  851.  *        readfrom    null
  852.  *        redraw        null
  853.  *        changesize    first byte indicates new size
  854.  *        spacebar    null
  855.  *        stoneplayed    x and y in the first two bytes
  856.  *        stepthrough    null
  857.  *        undo        null
  858.  *        writeto        null
  859.  *        
  860.  *        This function handles the displaying of the menu (together
  861.  *        with the associated flags). The current move must be
  862.  *        displayed on the menu in a relevant place.
  863.  *        
  864.  * Globals affected:    buttonpressedlasttime
  865.  *            
  866.  */
  867. getinput ( action, actbuffer ) 
  868. ACTIONTYPE *action ;
  869. char       actbuffer[MAXLINELENGTH] ;
  870. {
  871. Titem *ret ;
  872. Point mouseat ;
  873. int keypressed ;
  874. byte width ;
  875.  
  876.     wait(MOUSE|KBD);
  877.     if (*action!=noselection)
  878.         cursswitch( &go_icon ) ;
  879.  
  880.     if (buttonpressedlasttime == TRUE)
  881.     {
  882.         /* need to sleep to avoid button bounce */
  883.         sleep(15) ;
  884.     }
  885.  
  886.     /* reset value */
  887.     buttonpressedlasttime = FALSE ;
  888.  
  889.     *action = noselection ;
  890.         if (button1())
  891.         {
  892.             *action = stoneplayed ;
  893.             mouseat = mouse.jxy ;
  894.             actbuffer[0]=(mouseat.x-LEDGE+(GRIDSIZE/2))/GRIDSIZE  + 1;
  895.             actbuffer[1]=(mouseat.y-LEDGE+(GRIDSIZE/2))/GRIDSIZE  + 1;
  896.             buttonpressedlasttime = TRUE ;
  897.         }
  898.  
  899.         if (button2())
  900.         {
  901.             *action = spacebar ;
  902.             buttonpressedlasttime = TRUE ;
  903.         }
  904.  
  905.         hgoto = 0 ; /* initialise */
  906.  
  907.         if (button3())
  908.         {
  909.             ret=tmenuhit (&menu00,3,TM_EXPAND) ;
  910.     
  911.  
  912.             if (ret!=0) 
  913.             {
  914.                 if (hgoto==0)
  915.                 {
  916.                     switch (ret->ufield.uval)
  917.                     {
  918.                         case size9 :
  919.                             actbuffer[0] = 9 ;
  920.                             *action = changesize ;
  921.                             break ;
  922.                         case size13 :
  923.                             actbuffer[0] = 13 ;
  924.                             *action = changesize ;
  925.                             break ;
  926.                         case size19 :
  927.                             actbuffer[0] = 19 ;
  928.                             *action = changesize ;
  929.                             break ;
  930.     
  931.                         case changehandicap :
  932.                             actbuffer[0] = dsize ;
  933.                             if (menu30.prevhit!=0)
  934.                             {
  935.                                 actbuffer[1] = menu30.prevhit+1 ;
  936.                             }
  937.                             else
  938.                             {
  939.                                 actbuffer[1] = 0 ;
  940.                             }
  941.                             *action = changehandicap ;
  942.                             break ;
  943.     
  944.                         default :
  945.                             *action = (ACTIONTYPE)ret->ufield.uval ;
  946.                             break  ;
  947.                     }
  948.                 }
  949.                 else
  950.                 {
  951.                     actbuffer[0] = 0 ;
  952.                     sprintf(actbuffer,"%d\n",hgoto ) ;
  953.  
  954.                     if (dgoto==GOTOMOVE)
  955.                         *action = gotomove ;
  956.                     else
  957.                         *action = gotoline ;
  958.                 }
  959.             }
  960.  
  961.             buttonpressedlasttime = TRUE ;
  962.  
  963.         } /* end button 3 */
  964.     
  965.  
  966.         if ( (keypressed=kbdchar()) != (-1) )
  967.         {
  968.             if ((char)keypressed==' ')
  969.                 *action = spacebar ;
  970.             else
  971.             {
  972.                 *action = rawkeyboard ;
  973.                 actbuffer[0] = (char)keypressed ;
  974.                 width = jputc( Pt(XSTARTPOS,promptline),
  975.                            (char)keypressed,
  976.                            F_STORE) ;
  977.                 collectstring(Pt(XSTARTPOS,promptline),
  978.                           Pt(XSTARTPOS+width,promptline),
  979.                           actbuffer,1 , MAXCHARS ) ;
  980.                 strcat(actbuffer,"\n") ;
  981.             }
  982.  
  983.         } /* end if key pressed */
  984.  
  985. }
  986.  
  987.  
  988. /*
  989.  * Function:    drawgrid
  990.  *        
  991.  * Description:    Check if the grid flag is on , if so display the 'A' to 'T'
  992.  *        across the top and 19 to 1 down the left.
  993.  *        
  994.  *        
  995.  * Globals affected:    none
  996.  *            
  997.  */
  998. drawgrid()
  999. {
  1000. int i,j ;
  1001. char numberstring[3] ;
  1002.  
  1003.     if (flag[GRID]==on)
  1004.     {
  1005.         for (i=1;i<=size;i++)
  1006.             for (j=1;j<=size;j++)
  1007.             {
  1008.                 if (i==1)
  1009.                 {
  1010.                     ctostr(size-j+1,numberstring) ;
  1011.                     (void)jputs( 0,
  1012.                              ((j-1)*GRIDSIZE)+LEDGE-(fontheight/2),
  1013.                              numberstring ) ;
  1014.                            
  1015.                 }
  1016.                 if (j==1)
  1017.                 {
  1018.                     if (i<=8)
  1019.                         (void)jputc((i-1)*GRIDSIZE+LEDGE,10+(fontheight/2),i+'A'-1) ;
  1020.                     else
  1021.                         (void)jputc((i-1)*GRIDSIZE+LEDGE,10+(fontheight/2),i+'J'-9) ;
  1022.                 }
  1023.             }
  1024.  
  1025.     }
  1026. }
  1027.  
  1028. /*
  1029.  * Function:    drawempty
  1030.  *        
  1031.  * Description:    Draws an empty position of the board, if this x,y is a handicap
  1032.  *        point then draw a black dot as well.
  1033.  *        
  1034.  *        
  1035.  * Globals affected:    none
  1036.  *            
  1037.  */
  1038. drawempty(x,y)
  1039. COORD x,y ;
  1040. {
  1041. Point actual ;
  1042.  
  1043.  
  1044.     if ( (x==1) && (y==1) )
  1045.     {
  1046.         jbox(Rect(LEDGE-STONERADIUS-2,
  1047.               LEDGE-STONERADIUS-2,
  1048.               HEDGE+STONERADIUS+2,
  1049.               HEDGE+STONERADIUS+2) ) ;
  1050.     }
  1051.  
  1052.     actual.x = (x-1)*GRIDSIZE+LEDGE;
  1053.     actual.y = (y-1)*GRIDSIZE+LEDGE ;
  1054.  
  1055.     jdisc(actual,STONERADIUS,F_CLR) ;
  1056.  
  1057.     switch ( (int)postype(x,y) )
  1058.     {
  1059.         case topleft :
  1060.             jsegment(Pt(LEDGE,LEDGE),
  1061.                  Pt(LEDGE+STONERADIUS+GAP,LEDGE),
  1062.                  F_STORE ) ;
  1063.             jsegment(Pt(LEDGE,LEDGE),
  1064.                  Pt(LEDGE,LEDGE+STONERADIUS+GAP),
  1065.                  F_STORE ) ;
  1066.             break ;
  1067.         case topside :
  1068.             jsegment(Pt(actual.x-STONERADIUS,LEDGE),
  1069.                  Pt(actual.x+STONERADIUS+GAP,LEDGE),
  1070.                  F_STORE ) ;
  1071.             jsegment(Pt(actual.x,LEDGE),
  1072.                  Pt(actual.x,LEDGE+STONERADIUS+GAP),
  1073.                  F_STORE ) ;
  1074.             break ;
  1075.         case topright :
  1076.             jsegment(Pt(HEDGE-STONERADIUS,LEDGE),
  1077.                  Pt(HEDGE,LEDGE),
  1078.                  F_STORE ) ;
  1079.             jsegment(Pt(HEDGE,LEDGE),
  1080.                  Pt(HEDGE,LEDGE+STONERADIUS+GAP),
  1081.                  F_STORE ) ;
  1082.             break ;
  1083.         case leftside :
  1084.             jsegment(Pt(LEDGE,actual.y),
  1085.                  Pt(LEDGE+STONERADIUS+GAP,actual.y),
  1086.                  F_STORE ) ;
  1087.             jsegment(Pt(LEDGE,actual.y-STONERADIUS),
  1088.                  Pt(LEDGE,actual.y+STONERADIUS+GAP),
  1089.                  F_STORE ) ;
  1090.             break ;
  1091.         case middle :
  1092.             jsegment(Pt(actual.x-STONERADIUS,actual.y),
  1093.                  Pt(actual.x+STONERADIUS+GAP,actual.y),
  1094.                  F_STORE ) ;
  1095.             jsegment(Pt(actual.x,actual.y-STONERADIUS),
  1096.                  Pt(actual.x,actual.y+STONERADIUS+GAP),
  1097.                  F_STORE ) ;
  1098.             if (starpoint(x,y))
  1099.             {
  1100.                 putstar(actual) ;
  1101.             }
  1102.             break ;
  1103.         case rightside :
  1104.             jsegment(Pt(HEDGE-STONERADIUS,actual.y),
  1105.                  Pt(HEDGE,actual.y),
  1106.                  F_STORE ) ;
  1107.             jsegment(Pt(actual.x,actual.y-STONERADIUS),
  1108.                  Pt(actual.x,actual.y+STONERADIUS+GAP),
  1109.                  F_STORE ) ;
  1110.             break ;
  1111.         case bottomleft :
  1112.             jsegment(Pt(LEDGE,HEDGE),
  1113.                  Pt(LEDGE+STONERADIUS+GAP,HEDGE),
  1114.                  F_STORE ) ;
  1115.             jsegment(Pt(LEDGE,HEDGE-STONERADIUS),
  1116.                  Pt(LEDGE,HEDGE),
  1117.                  F_STORE ) ;
  1118.             break ;
  1119.         case bottomside :
  1120.             jsegment(Pt(actual.x-STONERADIUS,HEDGE),
  1121.                  Pt(actual.x+STONERADIUS+GAP,HEDGE),
  1122.                  F_STORE ) ;
  1123.             jsegment(Pt(actual.x,HEDGE-STONERADIUS),
  1124.                  Pt(actual.x,HEDGE),
  1125.                  F_STORE ) ;
  1126.             break ;
  1127.         case bottomright :
  1128.             jsegment(Pt(HEDGE-STONERADIUS,HEDGE),
  1129.                  Pt(HEDGE,HEDGE),
  1130.                  F_STORE ) ;
  1131.             jsegment(Pt(HEDGE,HEDGE-STONERADIUS),
  1132.                  Pt(HEDGE,HEDGE),
  1133.                  F_STORE ) ;
  1134.             break ;
  1135.         default :
  1136.             errorprint ( "error in draw empty" ) ;
  1137.             break ;
  1138.     }
  1139. }
  1140.  
  1141. /*
  1142.  * Function:    drawstone
  1143.  *        
  1144.  * Description:    Draw a stone of colour c at coordinates (x,y), the move number
  1145.  *        is n. Do not display the number if this is a handicap stone or
  1146.  *        practice flag is on or if numbers flag is off.
  1147.  *        
  1148.  * Globals affected:    none
  1149.  *            
  1150.  */
  1151. drawstone(x,y,n,colour)
  1152. COORD x,y ;
  1153. MOVENUMBER n ;
  1154. COLOUR colour ;
  1155. {
  1156.  
  1157. Point actual ;
  1158.  
  1159.  
  1160.     if ( (x==1) && (y==1) )
  1161.     {
  1162.         jbox(Rect(LEDGE-STONERADIUS-2,
  1163.               LEDGE-STONERADIUS-2,
  1164.               HEDGE+STONERADIUS+2,
  1165.               HEDGE+STONERADIUS+2) ) ;
  1166.     }
  1167.  
  1168.     actual.x = (x-1)*GRIDSIZE+LEDGE;
  1169.     actual.y = (y-1)*GRIDSIZE+LEDGE ;
  1170.  
  1171.  
  1172.     if (starpoint(x,y) && (n==2) && (handicap!=0) )
  1173.     {
  1174.         jdisc (actual, STONERADIUS, F_OR ) ;
  1175.     }
  1176.     else
  1177.         if (colour==black)
  1178.         {
  1179.             jdisc (actual, STONERADIUS, F_OR ) ;
  1180.                 if ( (flag[PRACTICE]==off) &&
  1181.                      (flag[NUMBERS]==on) )
  1182.                     putnumber(actual,black,n) ;
  1183.         }
  1184.         else
  1185.             if (colour==white)
  1186.             {
  1187.                 jdisc (actual, STONERADIUS, F_CLR ) ;
  1188.                 jcircle ( actual, STONERADIUS, F_OR ) ;
  1189.                 if ( (flag[PRACTICE]==off) &&
  1190.                      (flag[NUMBERS]==on) )
  1191.                     putnumber(actual,white,n) ;
  1192.             }
  1193.             else
  1194.             {
  1195.                 errorprint("error in drawstone") ;
  1196.             }
  1197.     
  1198.     switch ( (int)postype(x,y) )
  1199.     {
  1200.         case topleft :
  1201.             jsegment ( Pt(LEDGE+STONERADIUS,LEDGE),
  1202.                    Pt(LEDGE+STONERADIUS+GAP,LEDGE),
  1203.                    F_STORE ) ;
  1204.             jsegment ( Pt(LEDGE,LEDGE+STONERADIUS),
  1205.                    Pt(LEDGE,LEDGE+STONERADIUS+GAP),
  1206.                    F_STORE ) ;
  1207.             break ;
  1208.                   
  1209.         case topside :
  1210.             jsegment ( Pt(actual.x+STONERADIUS,LEDGE),
  1211.                    Pt(actual.x+STONERADIUS+GAP,LEDGE),
  1212.                    F_STORE ) ;
  1213.             jsegment ( Pt(actual.x,LEDGE+STONERADIUS),
  1214.                    Pt(actual.x,LEDGE+STONERADIUS+GAP),
  1215.                    F_STORE ) ;
  1216.             break ;
  1217.             
  1218.         case topright :
  1219.             jsegment ( Pt(HEDGE,LEDGE+STONERADIUS),
  1220.                    Pt(HEDGE,LEDGE+STONERADIUS+GAP),
  1221.                    F_STORE ) ;
  1222.             break ;
  1223.                   
  1224.         case leftside:
  1225.             jsegment ( Pt(LEDGE+STONERADIUS,actual.y),
  1226.                    Pt(LEDGE+STONERADIUS+GAP,actual.y),
  1227.                    F_STORE ) ;
  1228.             jsegment ( Pt(LEDGE,actual.y+STONERADIUS),
  1229.                    Pt(LEDGE,actual.y+STONERADIUS+GAP),
  1230.                    F_STORE ) ;
  1231.             break ;
  1232.                   
  1233.         case middle :
  1234.             jsegment ( Pt(actual.x+STONERADIUS,actual.y),
  1235.                    Pt(actual.x+STONERADIUS+GAP,actual.y),
  1236.                    F_STORE ) ;
  1237.             jsegment ( Pt(actual.x,actual.y+STONERADIUS),
  1238.                    Pt(actual.x,actual.y+STONERADIUS+GAP),
  1239.                    F_STORE ) ;
  1240.             break ;
  1241.  
  1242.         case rightside :
  1243.             jsegment ( Pt(HEDGE,actual.y+STONERADIUS),
  1244.                    Pt(HEDGE,actual.y+STONERADIUS+GAP),
  1245.                    F_STORE ) ;
  1246.             break ;
  1247.                   
  1248.         case bottomleft :
  1249.             jsegment ( Pt(LEDGE+STONERADIUS,HEDGE),
  1250.                    Pt(LEDGE+STONERADIUS+GAP,HEDGE),
  1251.                    F_STORE ) ;
  1252.             break ;
  1253.  
  1254.         case bottomside :
  1255.             jsegment ( Pt(actual.x+STONERADIUS,HEDGE),
  1256.                    Pt(actual.x+STONERADIUS+GAP,HEDGE),
  1257.                    F_STORE ) ;
  1258.             break ;
  1259.  
  1260.         case bottomright :
  1261.             break ;
  1262.  
  1263.         default :
  1264.             errorprint("error in case in drawstone") ;
  1265.             break ;
  1266.  
  1267.     } /* end switch postype */
  1268.  
  1269. }
  1270.  
  1271. /*
  1272.  * Function:    getdirectory
  1273.  *        
  1274.  * Description:    If directory is already set then copy directory into dn.
  1275.  *        Display dn, and allow editting of it with backspace and
  1276.  *        kill.
  1277.  *        
  1278.  * Globals affected:    none
  1279.  *            
  1280.  */
  1281. getdirectory(dn)
  1282. char dn[] ;
  1283. {
  1284. short w1,w2 ;
  1285.  
  1286.     clearpromptline() ;
  1287.  
  1288.     if (directory[0]!=0)
  1289.     {
  1290.         strcpy(dn,directory) ;
  1291.     }
  1292.     else
  1293.     {
  1294.         dn[0] = 0 ;
  1295.     }
  1296.  
  1297.     w1 = jputs(Pt(XSTARTPOS,promptline),"Enter directory : ",F_STORE) ;
  1298.  
  1299.     w2 = jputs(Pt(XSTARTPOS+w1,promptline),dn,F_STORE) ;
  1300.  
  1301.     collectstring(Pt(XSTARTPOS+w1,promptline),
  1302.               Pt(XSTARTPOS+w1+w2,promptline),
  1303.               dn,strlen(dn),
  1304.               MAXCHARS ) ;
  1305.  
  1306.     clearpromptline() ;
  1307. }
  1308.  
  1309. /*
  1310.  * Function:    getfilename
  1311.  *        
  1312.  * Description:    If filename is already set then copy filename into fn.
  1313.  *        Display fn, and allow editting of it with backspace and
  1314.  *        kill.
  1315.  *        
  1316.  * Globals affected:    none
  1317.  *            
  1318.  */
  1319. getfilename(fn)
  1320. char fn[] ;
  1321. {
  1322. short w1,w2 ;
  1323.  
  1324.     clearpromptline() ;
  1325.  
  1326.     if (filename[0]!=0)
  1327.     {
  1328.         strcpy(fn,filename) ;
  1329.     }
  1330.     else
  1331.     {
  1332.         fn[0] = 0 ;
  1333.     }
  1334.  
  1335.     w1 = jputs(Pt(XSTARTPOS,promptline),"Enter filename : ",F_STORE) ;
  1336.  
  1337.     w2 = jputs(Pt(XSTARTPOS+w1,promptline),fn,F_STORE) ;
  1338.  
  1339.     collectstring(Pt(XSTARTPOS+w1,promptline),
  1340.               Pt(XSTARTPOS+w1+w2,promptline),
  1341.               fn,strlen(fn),
  1342.               FILENAMELEN ) ;
  1343.  
  1344.     clearpromptline() ;
  1345. }
  1346.  
  1347. /*
  1348.  * Function:    displaycaptured
  1349.  *        
  1350.  * Description:    Display teh number of stones taken off.
  1351.  *        
  1352.  * Globals affected:    none
  1353.  *            
  1354.  */
  1355. void
  1356. displaycaptured()
  1357. {
  1358. Point actual ;
  1359.  
  1360.     actual.x = HEDGE + ( GRIDSIZE * 2 ) ;
  1361.     actual.y = LEDGE + ( GRIDSIZE * 2 ) ;
  1362.  
  1363.  
  1364.     jdisc (actual, STONERADIUS, F_OR ) ;
  1365.     putnumber(actual,black,blackcaptured) ;
  1366.  
  1367.     actual.y = LEDGE + ( GRIDSIZE * 3 ) ;
  1368.  
  1369.     jdisc (actual, STONERADIUS, F_CLR ) ;
  1370.     jcircle ( actual, STONERADIUS, F_OR ) ;
  1371.     putnumber(actual,white,whitecaptured) ;
  1372.  
  1373. }
  1374.  
  1375. /*
  1376.  * Function:    refreshmenu()
  1377.  *        
  1378.  * Description:    This function is called when some information on the menu
  1379.  *        has changed, the screen needs updating.
  1380.  *        
  1381.  *        
  1382.  * Globals affected:    none
  1383.  *            
  1384.  */
  1385. void
  1386. refreshmenu()
  1387. {
  1388.     displayflag(STEPPING) ;
  1389.     displayflag(PRACTICE) ;
  1390.     displayflag(NUMBERS) ;
  1391.     displayflag(GRID) ;
  1392.     displayflag(LASTMOVE) ;
  1393. }
  1394.  
  1395. /*
  1396.  * Function:    clearpromptline
  1397.  *        
  1398.  * Description:    Rather than scroll up the prompt display area, this routine
  1399.  *        increments promptline downwards until there is no room to
  1400.  *        write another line of text, in which case it clears the whole
  1401.  *        display area.
  1402.  *        
  1403.  * Globals affected:    promptline
  1404.  *            
  1405.  */
  1406. clearpromptline()
  1407. {
  1408.     if ( promptline + (fontheight*2) > YMAX ) 
  1409.     {
  1410.         jrectf ( Rpt(Pt(XSTARTPOS,HEDGE+STONERADIUS+fontheight),
  1411.                      Pt(XMAX-1,promptline+fontheight) ),
  1412.             F_CLR ) ;
  1413.         promptline = HEDGE + STONERADIUS + fontheight ;
  1414.     }
  1415.     else
  1416.         promptline += fontheight ;
  1417. }
  1418.  
  1419. /*
  1420.  * Function:    displaystring()
  1421.  *        
  1422.  * Description:    Display s on the promptline.
  1423.  *        
  1424.  * Globals affected:    none
  1425.  *            
  1426.  */
  1427. displaystring(s)
  1428. char *s ;
  1429. {
  1430.     (void)jputs(Pt(XSTARTPOS,promptline),s ,F_STORE) ;
  1431. }
  1432.  
  1433. /*
  1434.  * Function:    startterminalspecific
  1435.  *        
  1436.  * Description:    Initailise variables for start of program, cache the
  1437.  *        application if required in the parameters, reshape the
  1438.  *        window to be square taking the width already drawn to 
  1439.  *        be the size.
  1440.  *        
  1441.  * Globals affected:    fontheight, buttonpressedlasttime, promptline
  1442.  *            
  1443.  */
  1444. void
  1445. startterminalspecific(argc,argv)
  1446. int argc ;
  1447. char *argv[] ;
  1448. {
  1449.  
  1450. int i ;
  1451. int width ;
  1452. int newheight ;
  1453. int oldheight ;
  1454. int heightdiff ;
  1455.  
  1456.     width = Drect.corner.x - Drect.origin.x ;
  1457.     oldheight = Drect.corner.y - Drect.origin.y ;
  1458.     newheight = width ;
  1459.     heightdiff = newheight - oldheight ;
  1460.  
  1461.     reshape( Rpt( Pt( Drect.origin.x, Drect.origin.y - heightdiff/2 ),
  1462.               Pt( Drect.corner.x, Drect.corner.y + heightdiff/2 ) ) ) ;
  1463.  
  1464.  
  1465.     fontheight = initjput() ;
  1466.  
  1467.     request(MOUSE|KBD);
  1468.  
  1469.     cursswitch( &go_icon )  ;
  1470.  
  1471.     buttonpressedlasttime = FALSE ;
  1472.  
  1473.     promptline = fontheight ; /* start at the top of the screen*/
  1474.  
  1475.     /* "-c" in the parameters represents a request to cache */
  1476.     for (i=1 ; i<argc ; i++)
  1477.     {
  1478.         if (strcmp("-c",argv[i]) == 0 )
  1479.         {
  1480.             cache((char *)0,A_NO_SHOW) ;
  1481.         }
  1482.     }
  1483. }
  1484.  
  1485. /*
  1486.  * Function:    endterminalspecific
  1487.  *        
  1488.  * Description:    The program is closing down, de-initialise any data, release
  1489.  *        resources etc.
  1490.  *        (no action required for the 630)
  1491.  *        
  1492.  * Globals affected:    none
  1493.  *            
  1494.  */
  1495. void
  1496. endterminalspecific()
  1497. {
  1498. }
  1499.  
  1500. /******************************/
  1501. /* End of Interface Functions */
  1502. /******************************/
  1503.  
  1504.  
  1505. /*
  1506.  * Function:    displayflag()
  1507.  *        
  1508.  * Description:    Display the required flag on the menu.
  1509.  *        
  1510.  * Globals affected:    none
  1511.  *            
  1512.  */
  1513. displayflag(f)
  1514. char f ;
  1515. {
  1516. Bitmap *symbol ;
  1517.  
  1518.     if (flag[f]==off)
  1519.         symbol = &bm_null ;
  1520.     else
  1521.         symbol = &bm_tick ;
  1522.  
  1523.  
  1524.     switch(f)
  1525.     {
  1526.         case STEPPING : rootmenu[1].icon = symbol ;
  1527.                 break ;
  1528.         case PRACTICE :    rootmenu[0].icon = symbol ;
  1529.                 break ;
  1530.         case NUMBERS :    configmenu[0].icon = symbol ;
  1531.                 break ;
  1532.         case GRID :    configmenu[1].icon = symbol ;
  1533.                 break ;
  1534.         case LASTMOVE :    configmenu[2].icon = symbol ;
  1535.                 break ;
  1536.         default :    errorprint("Default case in displayflag()") ;
  1537.                 break ;
  1538.     }
  1539. }
  1540.  
  1541. /*
  1542.  * Function:    downgoto
  1543.  *        
  1544.  * Description:    This function is entered when sliding down into goto a
  1545.  *        move or line.
  1546.  *        
  1547.  *        
  1548.  * Globals affected:    dgoto
  1549.  *            
  1550.  */
  1551. void
  1552. downgoto(mi)
  1553. Titem *mi ;
  1554. {
  1555.     dgoto = mi->ufield.uval ;
  1556. }
  1557.  
  1558. /*
  1559.  * Function:    downsize()
  1560.  *        
  1561.  * Description:    This is entered when the mouse slides down into the
  1562.  *        handicap menu.
  1563.  *        
  1564.  *        
  1565.  * Globals affected:    dsize
  1566.  *            
  1567.  */
  1568. void
  1569. downsize(mi)
  1570. Titem *mi ;
  1571. {
  1572.     switch (mi->ufield.uval)
  1573.     {
  1574.         case size9 :    handicapmenu[5].ufield.grey = 1 ;
  1575.                 handicapmenu[6].ufield.grey = 1 ;
  1576.                 handicapmenu[7].ufield.grey = 1 ;
  1577.                 handicapmenu[8].ufield.grey = 1 ;
  1578.                 dsize = 9 ;
  1579.                 break ;
  1580.         case size13 :    handicapmenu[5].ufield.grey = 1 ;
  1581.                 handicapmenu[6].ufield.grey = 1 ;
  1582.                 handicapmenu[7].ufield.grey = 1 ;
  1583.                 handicapmenu[8].ufield.grey = 1 ;
  1584.                 dsize = 13 ;
  1585.                 break ;
  1586.         case size19 :    handicapmenu[5].ufield.grey = 0 ;
  1587.                 handicapmenu[6].ufield.grey = 0 ;
  1588.                 handicapmenu[7].ufield.grey = 0 ;
  1589.                 handicapmenu[8].ufield.grey = 0 ;
  1590.                 dsize = 19 ;
  1591.                 break ;
  1592.         default :    errorprint("error in downsize");
  1593.                 break ;
  1594.     }
  1595.  
  1596.  
  1597.  
  1598. }
  1599.  
  1600. /*
  1601.  * Function:    hitgoto
  1602.  *        
  1603.  * Description:    This is entered when the mouse is clicked on the goto menu.
  1604.  *        
  1605.  *        
  1606.  * Globals affected:    hgoto
  1607.  *            
  1608.  */
  1609. void
  1610. hitgoto(mi)
  1611. Titem *mi ;
  1612. {
  1613.     hgoto = mi->ufield.uval ;
  1614. }
  1615.  
  1616.  
  1617. /*
  1618.  * Function:    gotogenerator()
  1619.  *        
  1620.  * Description:    This is entered when the goto menu is first selected, it
  1621.  *        dynamically generates the list of numbers to goto.
  1622.  *        
  1623.  *        
  1624.  * Globals affected:    gotomenuitem, s[]
  1625.  *            
  1626.  */
  1627. Titem gotomenuitem ;
  1628. char s[4] ;
  1629.  
  1630. Titem *
  1631. gotogenerator(i,m)
  1632.  
  1633. int i ;
  1634. Tmenu *m ;
  1635. {
  1636.  
  1637.     if (i>998)
  1638.     {
  1639.         gotomenuitem.text = 0 ;
  1640.  
  1641.         if (dgoto==GOTOMOVE)
  1642.         {
  1643.             if (currentmove < 9)
  1644.                 menu21.prevtop = 0 ;
  1645.             else
  1646.                 menu21.prevtop = currentmove - 10 ;
  1647.         }
  1648.         else
  1649.         {
  1650.             if (steppingindex < 8)
  1651.                 menu22.prevtop = 0 ;
  1652.             else
  1653.                 menu22.prevtop = steppingindex - 9 ;
  1654.         }
  1655.     }
  1656.     else
  1657.     {
  1658.         s[0] = 0 ;
  1659.         sprintf(s,"%d",i+1) ;
  1660.         gotomenuitem.text =  s ;
  1661.         gotomenuitem.ufield.uval = i + 1 ;
  1662.         if (dgoto==GOTOMOVE)
  1663.         {
  1664.             if ((currentmove-2) == i )
  1665.                 gotomenuitem.ufield.grey = 1 ;
  1666.             else
  1667.                 gotomenuitem.ufield.grey  = 0 ;
  1668.         }
  1669.         else
  1670.         {
  1671.             if ( (steppingindex-1) == i)
  1672.                 gotomenuitem.ufield.grey = 1 ;
  1673.             else
  1674.                 gotomenuitem.ufield.grey  = 0 ;
  1675.         }
  1676.         gotomenuitem.hfn = hitgoto ;
  1677.  
  1678.     }
  1679.  
  1680.     return(&gotomenuitem) ;
  1681. }
  1682.  
  1683.  
  1684. /*
  1685.  * Function:    ctostr()
  1686.  *        
  1687.  * Description:    Puts a right justified string of c into area pointed to
  1688.  *        by p. The length of p will always be three.
  1689.  *        
  1690.  *        
  1691.  * Globals affected:    none
  1692.  *            
  1693.  */
  1694. ctostr(c,p)
  1695. unsigned char c ;
  1696. char *p ;
  1697. {
  1698. #define LEN 3
  1699.     int dec,index ;
  1700.  
  1701.     for (index=0 ; index<LEN ;index ++)
  1702.     {
  1703.         *(p+index) = ' ' ;
  1704.     }
  1705.  
  1706.     *(p+LEN) = '\0' ;
  1707.  
  1708.     dec = LEN ;
  1709.  
  1710.     do
  1711.     {
  1712.         dec-- ;
  1713.         *(p+dec) = (c%10) + '0' ;
  1714.         c = c/10 ;
  1715.     }
  1716.     while (c!=0) ;
  1717.  
  1718. }
  1719.  
  1720.  
  1721.  
  1722. /*
  1723.  * Function:    collectstring()
  1724.  *        
  1725.  * Description:    Allows player to input and edit a string displayed on promptline
  1726.  *        Editting keys are backspace and delete (to kill a line)
  1727.  *        The resultant string is in p.
  1728.  *        
  1729.  * Globals affected:    none
  1730.  *            
  1731.  */
  1732. collectstring ( sat, at, p, l, max )
  1733. Point sat ; /* point to start of string already displayed */
  1734. Point at ; /*point at which to start displaying */
  1735. char *p ;  /* pointer to the buffer */
  1736. char l ;    /* length of buffer aleady filled */
  1737. char max ;    /* limit of number of characters */
  1738. {
  1739. char c,w ;
  1740.  
  1741.     cursswitch(&C_insert) ;    /* new cursor to prompt the player for text */
  1742.  
  1743.     w = 0 ;
  1744.     c = 0 ;
  1745.     while (c!=RETURN)
  1746.     {
  1747.         wait(KBD) ;
  1748.         c = (char)kbdchar() ;
  1749.         if (c!=(-1))
  1750.         {
  1751.             switch (c)
  1752.             {
  1753.                 case RETURN:
  1754.                     break ;
  1755.                 case BACKSPACE:
  1756.                     if (l>0)
  1757.                     {
  1758.                         l-- ;
  1759.                         w = jwidths(p+l) ;
  1760.                         at.x -= w ;
  1761.                         jrectf(Rpt(at,Pt(at.x+w,at.y+fontheight)),F_CLR) ;
  1762.                         jmove(at) ;
  1763.                         *(p+l) = '\0' ;
  1764.                     }
  1765.                     break ;
  1766.                 case KILLLINE:
  1767.                     at = sat ;
  1768.                     jrectf(Rpt(sat,Pt(1023,sat.y+fontheight)),F_CLR) ;
  1769.                     jmove(sat) ;
  1770.                     l = 0; 
  1771.                     break ;
  1772.                 default:
  1773.                     if ( l < max )
  1774.                     {
  1775.                         *(p+l) = (char)c ;
  1776.                         l++ ;
  1777.                         *(p+l) ='\0' ;
  1778.                         w = jputc(Pt(at.x,at.y),(char)c,F_STORE) ;
  1779.                         at.x += w ;
  1780.                     }
  1781.                     break ;
  1782.             }
  1783.         }
  1784.     }
  1785. }
  1786.  
  1787. /*
  1788.  * Function:    jbox
  1789.  *        
  1790.  * Description:    Draws a box scaled to the window
  1791.  *        
  1792.  *        
  1793.  *        
  1794.  * Globals affected:    none
  1795.  *            
  1796.  */
  1797. jbox(r)
  1798. Rectangle r;
  1799. {
  1800.     jsegment (r.origin, Pt(r.corner.x,
  1801.           r.origin.y), F_STORE);
  1802.     jsegment (Pt(r.corner.x, r.origin.y),
  1803.           r.corner, F_STORE);
  1804.     jsegment (r.corner, Pt(r.origin.x,
  1805.           r.corner.y), F_STORE);
  1806.     jsegment (Pt(r.origin.x, r.corner.y),
  1807.           r.origin, F_STORE);
  1808. }
  1809.  
  1810. /*
  1811.  * Function:    putnumber
  1812.  *        
  1813.  * Description:    Puts a number n onto the stone at point p whose colur is c.
  1814.  *        
  1815.  * Globals affected:    none
  1816.  *            
  1817.  */
  1818. putnumber(p,c,n)
  1819. Point p ;
  1820. COLOUR c ;
  1821. MOVENUMBER n ;
  1822. {
  1823. short width ;
  1824. char str[4] ;
  1825. Code f ;
  1826.  
  1827.     if (c==black)
  1828.         f=F_CLR ;
  1829.     else
  1830.         f=F_STORE ;
  1831.  
  1832.     ctostr((unsigned char)n,str) ;
  1833.  
  1834.     if (n<10)
  1835.     {
  1836.         width =jwidths(&str[2]) ;
  1837.         jputs(Pt(p.x-(width/2),p.y-(fontheight/2)), &str[2], f ) ;
  1838.     } else
  1839.     if (n<100)
  1840.     {
  1841.         width =jwidths(&str[1]) ;
  1842.         jputs(Pt(p.x-(width/2),p.y-(fontheight/2)), &str[1], f ) ;
  1843.     } else
  1844.     if (n<1000)
  1845.     {
  1846.         width =jwidths(str) ;
  1847.         jputs(Pt(p.x-(width/2),p.y-(fontheight/2)), str, f ) ;
  1848.     }
  1849.  
  1850. }
  1851.  
  1852. /*
  1853.  * Function:    putstar()
  1854.  *        
  1855.  * Description:    Draws a star point (a black dot) at p.
  1856.  *        
  1857.  *        
  1858.  *        
  1859.  * Globals affected:    none
  1860.  *            
  1861.  */
  1862. putstar(p)
  1863. Point p ;
  1864. {
  1865.     jdisc(p,STONERADIUS/3,F_STORE) ;
  1866. }
  1867.  
  1868. /*
  1869.  * Jput routines
  1870.  *
  1871.  * These functions look directly at the memory location for the built-in
  1872.  * 'Large' font and use jpoint to display each individual bit/pixel so
  1873.  * that the text is scaled to the window.
  1874.  */
  1875.  
  1876.  
  1877.  
  1878. char *pbitmap ;    /* pointer to the start of the bitmap */
  1879. Font *font;
  1880. Fontchar *i;
  1881.  
  1882.  
  1883. char
  1884. initjput()    /* need to initialise the global data */
  1885. {
  1886.     font = &largefont;
  1887.     pbitmap = (char *)font->bits->base;
  1888.     return(font->height) ;
  1889. }
  1890.  
  1891. short
  1892. jwidths(s)    /* return the width of s in pixels */
  1893. char *s ;
  1894. {
  1895. short swidth ;
  1896. byte cwidth ;
  1897.  
  1898.  
  1899.     swidth = 0 ;
  1900.     while (*s!='\0')
  1901.     {
  1902.         i = (Fontchar *)((char *)font + 12 + ( 6 * (*s) ) );
  1903.         swidth += (i->width) ;
  1904.         s++ ;
  1905.     }
  1906.  
  1907.     return (swidth) ;
  1908.  
  1909. }
  1910. short
  1911. jputs(p,s,f)    /* put a string s starting at p using f format */
  1912. Point p ;
  1913. char *s ;
  1914. Code f ;
  1915. {
  1916. short swidth ;
  1917. byte cwidth ;
  1918.  
  1919.  
  1920.     swidth = 0 ;
  1921.     while ( (*s!='\0') && (*s!='\n') )
  1922.     {
  1923.         cwidth = jputc(Pt(p.x+swidth,p.y),*s,f) ;
  1924.         swidth += cwidth ;
  1925.         s++ ;
  1926.     }
  1927.  
  1928.     return (swidth) ;
  1929.  
  1930. }
  1931.  
  1932. byte
  1933. jputc( p, c, f )    /* put a char c at p using format f */
  1934. Point p;
  1935. char c;
  1936. Code f ;
  1937. {
  1938.  
  1939. register xindex,yindex ;
  1940. byte Nthbit() ;
  1941.  
  1942.     if (c=='\t') c=' ' ; /* screen tabs */
  1943.  
  1944.     i = (Fontchar *)((char *)font + 12 + ( 6*c) );
  1945.  
  1946.  
  1947.     for (xindex=(i->left) ; xindex < (i->width) ; xindex++ )
  1948.     {
  1949.         for (yindex=(i->top) ; yindex <= (i->bottom) ; yindex++ )
  1950.         {
  1951.             if (Nthbit( (i->x)+xindex +
  1952.                     ( yindex * (font->bits->width) * 16 ) ) )
  1953.             {
  1954.                 jpoint (Pt(p.x+xindex,p.y+yindex),f) ;
  1955.             }
  1956.         }
  1957.     }
  1958.  
  1959.     return (i->width) ;
  1960. }
  1961.  
  1962.  
  1963. byte
  1964. Nthbit (N)    /* Returns the value of the Nth bit after pbitmap */
  1965. int N ;
  1966. {
  1967. char actualbyte ;
  1968. byte shiftindex ;
  1969.  
  1970.     actualbyte = *(pbitmap + (N/8) ) ;
  1971.  
  1972.     shiftindex = 7 - (N%8) ;
  1973.  
  1974.     return( (actualbyte>>shiftindex) & 0x01) ;
  1975. }
  1976. SHAR_EOF
  1977. fi
  1978. if test -f 'go.c'
  1979. then
  1980.     echo shar: "will not over-write existing file 'go.c'"
  1981. else
  1982. cat << \SHAR_EOF > 'go.c'
  1983. #include <string.h>
  1984. #include <sys/types.h>
  1985.  
  1986. #include "go.h"
  1987. #include "go.interface.h"
  1988. #include "go.patch.h"
  1989.  
  1990.  
  1991. #include <malloc.h>
  1992.  
  1993.  
  1994. /****************************************************************************/
  1995. /*           Global variables                                               */
  1996. /****************************************************************************/
  1997.  
  1998. char version[] = "v1.0" ;
  1999. char size ;    /* size of the board */
  2000. char handicap ;    /* number of handicap stones */
  2001.  
  2002. COLOUR black ;
  2003. COLOUR white ;
  2004.  
  2005. MOVENUMBER currentmove ;    /* currentmove is the number of the next stone
  2006.                  * to be played for 'real' ie not practice
  2007.                  */
  2008.  
  2009. int steppingindex ;        /* used while stepping through raw[] */
  2010.                 /* Points to the next one to translate */
  2011.  
  2012. char filename[FILENAMELEN] ;
  2013. char directory[MAXLINELENGTH] ;
  2014.  
  2015. ONOFF flag[5] ;
  2016.  
  2017. int blackcaptured ;
  2018. int whitecaptured ;
  2019.  
  2020. /*
  2021.  * Explanation of terms :-
  2022.  *    "Raw" is used to describe text input by  the player to represent
  2023.  *    a move eg 'K5' or 'pass' this has to be "translated" into the x
  2024.  *    and y coordinates of the board. "conversion" is when the (x,y)
  2025.  *    coordinates have to presented as "raw".
  2026.  */
  2027.  
  2028. /********************************************/
  2029. /* Types and defines just used in this file */
  2030. /********************************************/
  2031.  
  2032. typedef enum RAWTYPE
  2033. {
  2034.     nullraw,
  2035.     amove,
  2036.     newgame,
  2037.     control,
  2038.     rawerror,
  2039. } RAWTYPE ;
  2040.  
  2041. #define MAXRAW 400
  2042.  
  2043. #define ILLEGALAT "Illegal move or unrecognised input at line "
  2044. #define ILLEGAL "Illegal move or unrecognised input"
  2045.  
  2046. /***************************************/
  2047. /* Static variables just for this file */
  2048. /***************************************/
  2049.  
  2050. FILE *fptr ;
  2051.  
  2052. /* These "saved" variables are to restore after an undo command */
  2053. int savedblackcaptured ;
  2054. int savedwhitecaptured ;
  2055. MOVENUMBER savedcurrentmove ;
  2056. COLOUR savednextpracticestone ;
  2057. XY savedkomove ;
  2058. char savedlastmovestring[5] ;
  2059.  
  2060.  
  2061. char tempfilename[FILENAMELEN] ;
  2062. char tempdirectory[MAXLINELENGTH] ;
  2063.  
  2064. /* Used in directoryplus() */
  2065. char fullfilename[MAXLINELENGTH + FILENAMELEN] ;
  2066.  
  2067. char *raw[MAXRAW] ;        /* Array of pointers to the
  2068.                  * text of a file read in or
  2069.                  * moves entered by players
  2070.                  */
  2071.  
  2072. int rawindex ;            /* The number of elements in raw[] */
  2073.  
  2074. int writeindex ;        /* Number of elements in raw[] written away*/
  2075.  
  2076. int undorawindex ;        /* Marker of when the board was last saved */
  2077.  
  2078. int lastreconfigure ;        /* Marker of when the current game started */
  2079.  
  2080. MOVENUMBER realboard[MAX][MAX] ;    /* Moves are stored in these arrays */
  2081. MOVENUMBER practiceboard[MAX][MAX] ;    /* by movenumber, eg if an element is */
  2082. MOVENUMBER undoboard[MAX][MAX] ;    /* zero that position is empty */
  2083. MOVENUMBER undopracticeboard[MAX][MAX] ;
  2084.  
  2085. COLOUR nextpracticestone ;    /* During practice this is the 'colour'
  2086.                  * of the next practice stone.
  2087.                  */
  2088.  
  2089. /* Positions of the star points (the middle */
  2090. /* point of a 19x19 is treated differently) */
  2091. XY handicap9[5] = { {3,7} , {7,3} , {7,7} , {3,3} , {5,5} } ;
  2092. XY handicap13[5] = { {4,10} , {10,4} , {10,10} , {4,4} , {7,7} } ;
  2093. XY handicap19[8] = { {4,16} , {16,4} , {16,16} , {4,4} ,
  2094.              {4,10} , {16,10} , {10,4} , {10,16} } ;
  2095.  
  2096. /* Used in checkcapture() checksurrounded() docheck() */
  2097. int captured ;    
  2098. int checking ;
  2099. XY deadstones[100] ; /* this list starts at 1 */
  2100.  
  2101.  
  2102. XY komove ;    /* stores the ko position, otherwise both fields are zero */
  2103.  
  2104. char lastmovestring[5] ; /* A raw string of the last move */
  2105.  
  2106.  
  2107.  
  2108.  
  2109. /*
  2110.  * Function:    copyboard
  2111.  *        
  2112.  * Description:    Copies an array from one to the other.
  2113.  *        
  2114.  *        
  2115.  *        
  2116.  * Globals affected:    none
  2117.  *            
  2118.  */
  2119. copyboard(from,to)
  2120. MOVENUMBER from[MAX][MAX] ;
  2121. MOVENUMBER to[MAX][MAX] ;
  2122. {
  2123. int i,j ;
  2124.  
  2125.     for (i=1;i<=size;i++)
  2126.         for (j=1;j<=size;j++)
  2127.             to[i][j] = from[i][j] ;
  2128. }
  2129.  
  2130. /*
  2131.  * Function:    stonecolour
  2132.  *        
  2133.  * Description:    Works on the number of the stone  to determine it's 
  2134.  *        colour. If the number is odd and there is no handicap,
  2135.  *        or if the number is even and there is a handicap then 
  2136.  *        the colour is black, else it is white.
  2137.  *        
  2138.  *        
  2139.  *        
  2140.  * Globals affected:    none
  2141.  *            
  2142.  */
  2143. COLOUR
  2144. stonecolour(n)
  2145. MOVENUMBER n ;
  2146. {
  2147. COLOUR retval ;
  2148.  
  2149.     if (n==0)
  2150.         retval = EMPTY ;
  2151.     else
  2152.     {
  2153.         if ( ((handicap!=0) && ((n%2)==0)) ||
  2154.              ((handicap==0) && ((n%2)!=0)) )
  2155.             retval = black ;
  2156.         else
  2157.             retval = white ;
  2158.     }
  2159.  
  2160.     return(retval) ;
  2161. }
  2162.  
  2163. /*
  2164.  * Function:    directoryplus
  2165.  *        
  2166.  * Description:    Returns a pointer to string that contains the directory
  2167.  *        plus the filename passed as parameter
  2168.  *        
  2169.  *        
  2170.  *        
  2171.  * Globals affected:    fullfilename[]
  2172.  *            
  2173.  */
  2174. char *
  2175. directoryplus(fn)
  2176. char *fn ;
  2177. {
  2178.     fullfilename[0] =0 ;
  2179.     strcat(fullfilename,directory) ;
  2180.     strcat(fullfilename,"/") ;
  2181.     strcat(fullfilename,fn) ;
  2182.  
  2183.     return(fullfilename) ;
  2184. }
  2185.  
  2186. /*
  2187.  * Function:    drawboard()
  2188.  *        
  2189.  * Description:    Draws the realboard[][] according to size and flag[GRID] and
  2190.  *        also shows the number of stones captured.
  2191.  *        
  2192.  *        
  2193.  * Globals affected:    none
  2194.  *            
  2195.  */
  2196. drawboard()
  2197. {
  2198.  
  2199. COORD i,j ;
  2200. MOVENUMBER stonenumber ;
  2201.  
  2202.     for (i=1;i<=size;i++)
  2203.         for (j=1;j<=size;j++)
  2204.             {
  2205.                 if (flag[PRACTICE]==off)
  2206.                     stonenumber = realboard[i][j] ;
  2207.                 else
  2208.                     stonenumber = practiceboard[i][j] ;
  2209.  
  2210.                 placestone(i,j,stonenumber) ;
  2211.             }
  2212.     drawgrid() ;
  2213.  
  2214.     displaycaptured() ;
  2215.  
  2216.     displaylastmove(lastmovestring) ;
  2217. }
  2218.  
  2219. /*
  2220.  * Function:    putstarpoints()
  2221.  *        
  2222.  * Description:    Initialises realboard[][] with the handicap stones
  2223.  *        (which always have a 'move number' of two)
  2224.  *        
  2225.  *        
  2226.  * Globals affected:    realboard[][]
  2227.  *            
  2228.  */
  2229. putstarpoints()
  2230. {
  2231. int i ;
  2232. int temphandicap ;
  2233.  
  2234.     if (size==9)
  2235.     {
  2236.         for (i=0;i<handicap;i++)
  2237.         {
  2238.             realboard[handicap9[i].x][handicap9[i].y] = black ;
  2239.         }
  2240.     }
  2241.     if (size==13)
  2242.     {
  2243.         for (i=0;i<handicap;i++)
  2244.         {
  2245.             realboard[handicap13[i].x][handicap13[i].y] = black ;
  2246.         }
  2247.     }
  2248.     if (size==19)
  2249.     {
  2250.         if ( (handicap==5) ||
  2251.              (handicap==7) ||
  2252.              (handicap==9) )
  2253.         {
  2254.             temphandicap = handicap - 1 ;
  2255.             realboard[10][10] = black ;
  2256.         }
  2257.         else
  2258.         {
  2259.             temphandicap = handicap ;
  2260.         }
  2261.         for (i=0;i<temphandicap;i++)
  2262.         {
  2263.             realboard[handicap19[i].x][handicap19[i].y] = black ;
  2264.         }
  2265.     }
  2266. }
  2267.  
  2268. /*
  2269.  * Function:    postype
  2270.  *        
  2271.  * Description:    Returns a value that indicates what sort of position (x,y)
  2272.  *        is eg top left corner, right side etc
  2273.  *        
  2274.  *        
  2275.  * Globals affected:    none
  2276.  *            
  2277.  */
  2278. POSTYPE
  2279. postype(x,y)
  2280. COORD x,y ;
  2281. {
  2282.     if (x==1)
  2283.     {
  2284.         if (y==1)
  2285.         {
  2286.             return(topleft) ;
  2287.         }
  2288.         else if (y==size)
  2289.             {
  2290.                 return(bottomleft) ;
  2291.             }
  2292.             else
  2293.             {
  2294.                 return(leftside) ;
  2295.             }
  2296.     }
  2297.     else if (x==size)
  2298.         {
  2299.             if (y==1)
  2300.             {
  2301.                 return(topright) ;
  2302.             }
  2303.         else if (y==size)
  2304.             {
  2305.                 return(bottomright) ;
  2306.             }
  2307.             else
  2308.             {
  2309.                 return(rightside) ;
  2310.             }
  2311.         }
  2312.         else if (y==1)
  2313.             {
  2314.                 return(topside) ;
  2315.             }
  2316.             else if (y==size)
  2317.                 {
  2318.                     return(bottomside) ;
  2319.                 }
  2320.                 else
  2321.                 {
  2322.                     return(middle) ;
  2323.                 }
  2324. }
  2325.  
  2326. /*
  2327.  * Function:    starpoint()
  2328.  *        
  2329.  * Description:    Returns TRUE if x,y is a handicap point. This function is unused
  2330.  *        in this file but may be used by the terminal interface driver.
  2331.  *        
  2332.  *        
  2333.  * Globals affected:    none
  2334.  *            
  2335.  */
  2336. BOOLEAN
  2337. starpoint(x,y)
  2338. char x,y ;
  2339. {
  2340. BOOLEAN notfound ;
  2341. int indx;
  2342.  
  2343.     notfound = TRUE ;
  2344.     indx = 0  ;
  2345.  
  2346.     if (size==9)
  2347.     {
  2348.         while ( (indx < 5) && notfound )
  2349.         {
  2350.             if ( (handicap9[indx].x==x) &&
  2351.                  (handicap9[indx].y==y) )
  2352.             {
  2353.                 notfound = FALSE ;
  2354.             }
  2355.             else
  2356.             {
  2357.                 indx ++ ;
  2358.             }
  2359.         }
  2360.     }
  2361.  
  2362.     else
  2363.     if (size==13)
  2364.     {
  2365.         while ( (indx < 5) && notfound )
  2366.         {
  2367.             if ( (handicap13[indx].x==x) &&
  2368.                  (handicap13[indx].y==y) )
  2369.             {
  2370.                 notfound = FALSE ;
  2371.             }
  2372.             else
  2373.             {
  2374.                 indx ++ ;
  2375.             }
  2376.         }
  2377.     }
  2378.  
  2379.     else
  2380.     if (size==19)
  2381.     {
  2382.         if ( (x==10) && (y==10) )
  2383.         {
  2384.             notfound = FALSE ;
  2385.         }
  2386.  
  2387.         while ( (indx < 8) && notfound )
  2388.         {
  2389.             if ( (handicap19[indx].x==x) &&
  2390.                  (handicap19[indx].y==y) )
  2391.             {
  2392.                 notfound = FALSE ;
  2393.             }
  2394.             else
  2395.             {
  2396.                 indx ++ ;
  2397.             }
  2398.         }
  2399.     }
  2400.  
  2401.  
  2402.     if (notfound)
  2403.     {
  2404.         return(FALSE) ;
  2405.     }
  2406.     else
  2407.     {
  2408.         return(TRUE) ;
  2409.     }
  2410.  
  2411. }
  2412.  
  2413. /*
  2414.  * Function:    placestone()
  2415.  *        
  2416.  * Description:    Calls the terminal interface routines to draw the correct
  2417.  *        colour of stone.
  2418.  *        
  2419.  *        
  2420.  * Globals affected:    none
  2421.  *            
  2422.  */
  2423. placestone(x,y,n)
  2424. COORD x,y ;
  2425. MOVENUMBER n ;
  2426. {
  2427. COLOUR colour ;
  2428.  
  2429.  
  2430.  
  2431.     colour = stonecolour(n) ;
  2432.  
  2433.     if (colour==EMPTY)
  2434.     {
  2435.         drawempty(x,y) ;
  2436.     }
  2437.     else
  2438.     {
  2439.         drawstone(x,y,n,colour) ;
  2440.     }
  2441.  
  2442. }
  2443.  
  2444. /*
  2445.  * Function:    initialiseflags()
  2446.  *        
  2447.  * Description:    Sets grid, numbers and lastmove flags so that they
  2448.  *        are displayed. Called at the begining of every file.
  2449.  *        
  2450.  *        
  2451.  * Globals affected:    flag[]
  2452.  *            
  2453.  */
  2454. void
  2455. initialiseflags()
  2456. {
  2457.     flag[NUMBERS] = on ;
  2458.     flag[GRID] = on ;
  2459.     flag[LASTMOVE] = on ;
  2460. }
  2461.  
  2462. /*
  2463.  * Function:    zeroboard()
  2464.  *        
  2465.  * Description:    Initialises the realboard before a game.
  2466.  *        
  2467.  *        
  2468.  * Globals affected:    komove, realboard, blackcaptured, whitecaptured
  2469.  *            
  2470.  */
  2471. zeroboard()
  2472. {
  2473. COORD i,j ;
  2474.  
  2475.     blackcaptured = 0 ;
  2476.     whitecaptured = 0 ;
  2477.  
  2478.     komove.x = 0 ;
  2479.     komove.y = 0 ;
  2480.  
  2481.     lastmovestring[0] = 0 ;
  2482.  
  2483.     for (i=1;i<=size;i++)
  2484.         for (j=1;j<=size;j++)
  2485.             realboard[i][j] = 0 ;
  2486. }
  2487.  
  2488. /*
  2489.  * Function:    resetgame()
  2490.  *        
  2491.  * Description:    Called when there has been a reconfigure.
  2492.  *        
  2493.  *        
  2494.  *        
  2495.  * Globals affected:    size, handicap, rawindex, filename[]
  2496.  *            
  2497.  */
  2498. resetgame(s,h)
  2499. char s,h ;
  2500. {
  2501. int indx ;
  2502.  
  2503.     zeroboard() ;
  2504.  
  2505.     if ( s > (MAX-1) )
  2506.         s = (MAX-1) ;   /* (MAX-1) is max size of board */
  2507.  
  2508.     size = s ;
  2509.  
  2510.     if ( ( size==9 || size==13 || size==19 ) &&
  2511.              ( h < 10 && h > 1 ) )
  2512.     {
  2513.         if ( ( size==9 || size==13 ) && ( h > 5 ) )
  2514.             handicap = 5 ;
  2515.         else
  2516.             handicap = h ;
  2517.     }
  2518.     else
  2519.     {
  2520.         handicap = 0 ;
  2521.     }
  2522.  
  2523.     reconfigure() ;
  2524.     setstonecolour() ;
  2525.     putstarpoints() ;
  2526.     currentmove = 1 ;
  2527.  
  2528.     if (flag[STEPPING]==off)
  2529.     {
  2530.         /* So that files written away
  2531.          * dont include all the previous
  2532.          * stuff, zero rawindex. However
  2533.          * this routine can also be called
  2534.          * during 'going to a move' hence
  2535.          * this zeroing is conditional
  2536.          */
  2537.  
  2538.         if (rawindex>0) /* free the memory previously allocated */
  2539.         {
  2540.             for ( indx=0 ; indx < rawindex ; indx++ )
  2541.                 free( raw[indx] ) ;
  2542.         }
  2543.  
  2544.         rawindex = 0 ;
  2545.         filename[0] = 0 ;
  2546.         lastreconfigure = 0 ;
  2547.         steppingindex = 0  ;
  2548.  
  2549.     }
  2550.     else
  2551.     {
  2552.         lastreconfigure = steppingindex ;
  2553.     }
  2554.  
  2555.     refreshmenu() ;
  2556.  
  2557.     erasescreen() ;
  2558.     drawboard();
  2559. }
  2560.  
  2561. /*
  2562.  * Function:    samecolour
  2563.  *        
  2564.  * Description:    Returns TRUE if the stone is of the specified colour.
  2565.  *        
  2566.  *        
  2567.  * Globals affected:    none
  2568.  *            
  2569.  */
  2570. BOOLEAN
  2571. samecolour(s,c)
  2572. MOVENUMBER s ;    /* number of stone to be checked */
  2573. COLOUR c ;    /* colour to be checked against */
  2574. {
  2575. COLOUR stonescolour ;
  2576. BOOLEAN retval ;
  2577.  
  2578.     if (s==0)
  2579.         retval = FALSE ;
  2580.     else
  2581.     {
  2582.  
  2583.         if ( ((handicap!=0) && ((s%2)==0)) ||
  2584.              ((handicap==0) && ((s%2)!=0)) )
  2585.             stonescolour = black ;
  2586.         else
  2587.             stonescolour = white ;
  2588.  
  2589.         if (stonescolour==c) 
  2590.             retval = TRUE ;
  2591.         else
  2592.             retval = FALSE ;
  2593.     }
  2594.  
  2595.     return(retval) ;
  2596. }
  2597.  
  2598. /*
  2599.  * Function:    notindeadstones
  2600.  *        
  2601.  * Description:    Returns TRUE if (x,y) is not in the array deadstones[]
  2602.  *        
  2603.  *        
  2604.  * Globals affected:    none
  2605.  *            
  2606.  */
  2607. BOOLEAN
  2608. notindeadstones(x,y)
  2609. COORD x,y ;
  2610. {
  2611. int index ;
  2612. BOOLEAN retval ;
  2613.  
  2614.     retval = TRUE ;
  2615.     index = 0 ;
  2616.  
  2617.     while ( (index < checking) && (retval==TRUE) )
  2618.     {
  2619.         index++ ;
  2620.  
  2621.         if ( (deadstones[index].x==x) &&
  2622.              (deadstones[index].y==y) )
  2623.             retval = FALSE ;
  2624.  
  2625.     }
  2626.  
  2627.     return(retval) ;
  2628. }
  2629.  
  2630. /*
  2631.  * Function:    checksurrounded
  2632.  *        
  2633.  * Description:    (x,y) is the point neighbouring a stone of colour c. If (x,y)
  2634.  *        is occupied then there is a chance that c could be captured, 
  2635.  *        if (x,y) is of the same colour and not already in deadstones[]
  2636.  *        then put this in the list to continue the search.
  2637.  *        
  2638.  * Globals affected:    checking, deadstones[]
  2639.  *            
  2640.  */
  2641. BOOLEAN
  2642. checksurrounded(x,y,b,c)
  2643. COORD x,y ;
  2644. MOVENUMBER b[MAX][MAX] ;
  2645. COLOUR c ;
  2646. {
  2647. BOOLEAN retval ;
  2648.  
  2649.  
  2650.     if (b[x][y]==0)
  2651.     {
  2652.         retval = FALSE ;
  2653.     }
  2654.     else
  2655.     {
  2656.         retval = TRUE ;
  2657.         if (samecolour(b[x][y],c))
  2658.         { 
  2659.             if (notindeadstones(x,y))
  2660.             {
  2661.                 checking++ ;
  2662.                 deadstones[checking].x = x ;
  2663.                 deadstones[checking].y = y ;
  2664.             }
  2665.         }
  2666.     }
  2667.  
  2668.     return(retval) ;
  2669. }
  2670.  
  2671. /*
  2672.  * Function:    checkcapture
  2673.  *        
  2674.  * Description:    Searches a whole group of 'colour' to see if it is captured.
  2675.  *
  2676.  *        'captured' is the number already captured ie from deadstones[1]
  2677.  *        to deadstones[captured] are the stones already captured by this
  2678.  *        latest move (note the stones have not yet been taken off the
  2679.  *        board).
  2680.  *        From deadstones[captured] to deadstones[checking] is a group of
  2681.  *        stones that is yet to be decided if alive or not.
  2682.  *        
  2683.  * Globals affected:    captured, checking
  2684.  *            
  2685.  */
  2686. checkcapture(b,colour) 
  2687. MOVENUMBER b[MAX][MAX] ;
  2688. COLOUR colour ;
  2689. {
  2690. COORD x,y ;
  2691. int index ;
  2692. BOOLEAN surrounded ;
  2693. POSTYPE thispos ;
  2694.  
  2695.     index = 0 ;
  2696.     surrounded = TRUE ;
  2697.  
  2698.     while ( (index<(checking-captured)) && (surrounded) )
  2699.     {
  2700.  
  2701.         index++ ;
  2702.         x = deadstones[captured+index].x ;
  2703.         y = deadstones[captured+index].y ;
  2704.  
  2705.         thispos = postype(x,y) ;
  2706.  
  2707.         surrounded = FALSE ;
  2708.  
  2709.         switch((int)thispos)
  2710.         {
  2711.         case topleft :    if (checksurrounded(x+1,y,b,colour))
  2712.                    if (checksurrounded(x,y+1,b,colour))
  2713.                     surrounded = TRUE ;
  2714.                 break ;
  2715.  
  2716.         case topside :    if (checksurrounded(x+1,y,b,colour))
  2717.                    if (checksurrounded(x-1,y,b,colour))
  2718.                       if (checksurrounded(x,y+1,b,colour))
  2719.                         surrounded = TRUE ;
  2720.                 break ;
  2721.  
  2722.         case topright :    if (checksurrounded(x-1,y,b,colour))
  2723.                    if (checksurrounded(x,y+1,b,colour))
  2724.                     surrounded = TRUE ;
  2725.                 break ;
  2726.  
  2727.         case leftside :    if (checksurrounded(x+1,y,b,colour))
  2728.                    if (checksurrounded(x,y+1,b,colour))
  2729.                       if (checksurrounded(x,y-1,b,colour))
  2730.                         surrounded = TRUE ;
  2731.                 break ;
  2732.  
  2733.         case middle :    if (checksurrounded(x+1,y,b,colour))
  2734.                    if (checksurrounded(x-1,y,b,colour))
  2735.                       if (checksurrounded(x,y+1,b,colour))
  2736.                          if (checksurrounded(x,y-1,b,colour))
  2737.                         surrounded = TRUE ;
  2738.                 break ;
  2739.  
  2740.         case rightside :if (checksurrounded(x-1,y,b,colour))
  2741.                    if (checksurrounded(x,y+1,b,colour))
  2742.                       if (checksurrounded(x,y-1,b,colour))
  2743.                     surrounded = TRUE ;
  2744.                 break ;
  2745.  
  2746.         case bottomleft :if (checksurrounded(x+1,y,b,colour))
  2747.                     if (checksurrounded(x,y-1,b,colour))
  2748.                     surrounded = TRUE ;
  2749.                 break ;
  2750.  
  2751.         case bottomside :if (checksurrounded(x+1,y,b,colour))
  2752.                     if (checksurrounded(x-1,y,b,colour))
  2753.                        if (checksurrounded(x,y-1,b,colour))
  2754.                     surrounded = TRUE ;
  2755.                 break ;
  2756.  
  2757.         case bottomright :if (checksurrounded(x-1,y,b,colour))
  2758.                      if (checksurrounded(x,y-1,b,colour))
  2759.                     surrounded = TRUE ;
  2760.                 break ;
  2761.  
  2762.         } /* end switch */
  2763.     }
  2764.  
  2765.     if (surrounded)
  2766.         captured = checking ;
  2767.     else
  2768.         checking = 0 ;
  2769. }
  2770.  
  2771. /*
  2772.  * Function:    saveboard
  2773.  *        
  2774.  * Description:    Saves the variables used for an 'undo'
  2775.  *        
  2776.  *        
  2777.  *        
  2778.  * Globals affected:    undoboard[][], savedblackcaptured, savedwhitecaptured,
  2779.  *            savedcurrentmove, savedkomove,
  2780.  *            practiceboard[][], savednextpracticestone,
  2781.  *            savedlastmovestring, undorawindex, undopracticeboard[][]
  2782.  */
  2783. saveboard() 
  2784. {
  2785.  
  2786.     if (flag[PRACTICE]==off)
  2787.     {
  2788.         copyboard(realboard,undoboard) ;
  2789.         savedblackcaptured = blackcaptured ;
  2790.         savedwhitecaptured = whitecaptured ;
  2791.         savedcurrentmove = currentmove ;
  2792.         savedkomove = komove ;
  2793.         strcpy( savedlastmovestring, lastmovestring ) ;
  2794.  
  2795.         if (flag[STEPPING]==off)
  2796.             undorawindex = rawindex ;
  2797.         else
  2798.             undorawindex = steppingindex ;
  2799.     }
  2800.     else
  2801.     {
  2802.         copyboard(practiceboard,undopracticeboard) ;
  2803.         savednextpracticestone = nextpracticestone ;
  2804.         savedkomove = komove ;
  2805.     }
  2806. }
  2807.  
  2808. /*
  2809.  * Function:    playstone
  2810.  *        
  2811.  * Description:    Updates the movenumers if not practicing and the relevant
  2812.  *        board passed as a parameter then calls placestone() to draw
  2813.  *        it on the screen.
  2814.  *        
  2815.  * Globals affected:    currentmove, nextpracticestone, lastmovestring
  2816.  *            
  2817.  */
  2818. playstone(x,y,b)
  2819. COORD x,y;
  2820. MOVENUMBER b[MAX][MAX] ;
  2821. {
  2822. MOVENUMBER movenumber ;
  2823.  
  2824.  
  2825.     if (flag[PRACTICE]==off)
  2826.     {
  2827.         movenumber = currentmove ;
  2828.         currentmove++ ;
  2829.         b[x][y] = movenumber ;
  2830.  
  2831.         converttostring(x,y,lastmovestring) ;
  2832.         displaylastmove(lastmovestring) ;
  2833.     }
  2834.     else
  2835.     {
  2836.         b[x][y] = nextpracticestone ;
  2837.         movenumber = nextpracticestone ;
  2838.  
  2839.         if (nextpracticestone==black)
  2840.             {
  2841.                 nextpracticestone=white ;
  2842.             }
  2843.         else
  2844.             {
  2845.                 nextpracticestone=black ;
  2846.             }
  2847.  
  2848.     }
  2849.  
  2850.  
  2851.  
  2852.     placestone(x,y,movenumber) ;
  2853.  
  2854. }
  2855.  
  2856. /*
  2857.  * Function:    removecaptured
  2858.  *        
  2859.  * Description:    For all the stone referenced in deadstones[], zero the
  2860.  *        board passed as a parameter, then call placestone() to
  2861.  *        remove the stone from the screen.
  2862.  *        
  2863.  * Globals affected:    none
  2864.  *            
  2865.  */
  2866. void
  2867. removecaptured(b)
  2868. MOVENUMBER b[MAX][MAX] ;
  2869. {
  2870. int index ;
  2871. COORD x,y ;
  2872.  
  2873.     for (index=1;index<=captured;index++)
  2874.     {
  2875.         x = deadstones[index].x ;
  2876.         y = deadstones[index].y ;
  2877.         b[x][y] = 0 ;
  2878.         placestone(x,y,0) ;
  2879.     }
  2880. }
  2881.  
  2882. /*
  2883.  * Function:    docheck
  2884.  *        
  2885.  * Description:    If there is a stone at (x,y) and has the same colour as c,
  2886.  *        then store it in deadstones[] and search for all
  2887.  *        others of the same colour adjoining this one.
  2888.  *        
  2889.  *        
  2890.  * Globals affected:    checking, deadstones[]
  2891.  *            
  2892.  */
  2893. docheck(x,y,b,c)
  2894. COORD x,y ;
  2895. MOVENUMBER b[MAX][MAX] ;
  2896. COLOUR c ;
  2897. {
  2898.     if (samecolour(b[x][y],c))
  2899.     {
  2900.         if (notindeadstones(x,y))
  2901.         {
  2902.             checking = captured + 1 ;
  2903.             deadstones[checking].x = x ;
  2904.             deadstones[checking].y = y ;
  2905.             checkcapture(b,c) ;
  2906.         }
  2907.     }
  2908. }
  2909.  
  2910. /*
  2911.  * Function:    store()
  2912.  *        
  2913.  * Description:    Allocates memory and copies the string to that memory then
  2914.  *        assigns the next element in raw[] to reference the string
  2915.  *        
  2916.  *        
  2917.  * Globals affected:    raw[], rawindex
  2918.  *            
  2919.  */
  2920. void
  2921. store(s)
  2922. char *s ;
  2923. {
  2924.  
  2925.     if (rawindex==MAXRAW)
  2926.     {
  2927.         errorprint("raw buffer full") ;
  2928.     }
  2929.     else
  2930.     {
  2931.  
  2932.         raw[rawindex] = malloc((unsigned)strlen(s)) ;
  2933.         if (raw[rawindex]==NULL)
  2934.         {
  2935.             errorprint("No memory") ;
  2936.         }
  2937.         else
  2938.         {
  2939.             strcpy(raw[rawindex],s) ; 
  2940.             rawindex++ ;
  2941.         }
  2942.     }
  2943.  
  2944. }
  2945.  
  2946. /*
  2947.  * Function:    storenewgame
  2948.  *        
  2949.  * Description:    Writes into raw[] the new configuration
  2950.  *        
  2951.  *        
  2952.  *        
  2953.  * Globals affected:    none
  2954.  *            
  2955.  */
  2956. storenewgame(s,h)
  2957. char s,h ;
  2958. {
  2959. char sizestr[6] ;
  2960. char handicapstr[2] ;
  2961.  
  2962.     sizestr[0] = 0 ;
  2963.     sprintf( sizestr, "%d ", s) ;
  2964.  
  2965.     handicapstr[0] = 0 ;
  2966.     sprintf( handicapstr, "%d", h) ;
  2967.  
  2968.     strcat( sizestr, handicapstr ) ;
  2969.     strcat( sizestr, "\n" ) ;
  2970.  
  2971.     store( sizestr ) ;
  2972. }
  2973.  
  2974. /*
  2975.  * Function:    writefileaway
  2976.  *        
  2977.  * Description:    prompts the player for a file name if it is the same as the
  2978.  *        one entered for 'reading' last time then append from writeindex
  2979.  *        to rawindex in raw[] to the end of that file, else write the
  2980.  *        whole of raw[] out to the file and save the filename so that
  2981.  *        it can be appended to next time.
  2982.  *
  2983.  * Globals affected:    filename, tempfilename, fptr
  2984.  *            
  2985.  */
  2986. writefileaway()
  2987. {
  2988. int indx ;
  2989.  
  2990.     getfilename(tempfilename) ;
  2991.  
  2992.     if (tempfilename[0]!=0)
  2993.     {
  2994.         if (strcmp(filename,tempfilename)==0)
  2995.         {
  2996.             /* names are the same so append */
  2997.             fptr = fopen(directoryplus(filename),"a+") ;
  2998.             if (fptr==(FILE *)NULL)
  2999.             {
  3000.                 errorprint ("unable to open file") ;
  3001.             }
  3002.             else
  3003.             {
  3004.                 displaystring("appending") ;
  3005.                 for (indx=writeindex;indx<rawindex;indx++)
  3006.                 {
  3007.                     fputs(raw[indx],fptr) ;
  3008.                 }
  3009.     
  3010.                 fclose(fptr) ;
  3011.                 clearpromptline() ;
  3012.                 writeindex = rawindex ; 
  3013.             }
  3014.         }
  3015.         else
  3016.         {
  3017.             /* names different so write */
  3018.             fptr = fopen(directoryplus(tempfilename),"w") ;
  3019.             if (fptr==(FILE *)NULL)
  3020.             {
  3021.                 errorprint ("unable to open file") ;
  3022.             }
  3023.             else
  3024.             {
  3025.                 displaystring("writing") ;
  3026.                 for (indx=0;indx<rawindex;indx++)
  3027.                 {
  3028.                     fputs(raw[indx],fptr) ;
  3029.                 }
  3030.     
  3031.                 fclose(fptr) ;
  3032.                 clearpromptline() ;
  3033.                 writeindex = rawindex ; 
  3034.                 strcpy (filename,tempfilename) ;
  3035.             }
  3036.         }
  3037.     }
  3038.     else
  3039.     {
  3040.         clearpromptline() ;
  3041.     }
  3042.  
  3043. }
  3044.  
  3045. /*
  3046.  * Function:    passmove()
  3047.  *        
  3048.  * Description:    A player has passed, set relevant data accordingly.
  3049.  *        
  3050.  *        
  3051.  * Globals affected:    currentmove, komove, nextpracticestone
  3052.  *            lastmovestring[]
  3053.  */
  3054. void
  3055. passmove()
  3056. {
  3057.  
  3058.     saveboard() ;
  3059.  
  3060.     if (flag[PRACTICE]==off)
  3061.     {
  3062.         currentmove ++ ;
  3063.         komove.x = 0 ;
  3064.         komove.y = 0 ;
  3065.  
  3066.         converttostring(0,0,lastmovestring) ;
  3067.         displaylastmove(lastmovestring) ;
  3068.         refreshmenu() ;
  3069.     }
  3070.     else
  3071.     {
  3072.         if ( nextpracticestone==black)
  3073.         {
  3074.             nextpracticestone = white ;
  3075.         }
  3076.         else
  3077.         {
  3078.             nextpracticestone = black ;
  3079.         }
  3080.         komove.x = 0 ;
  3081.         komove.y = 0 ;
  3082.     }
  3083. }
  3084.  
  3085. /*
  3086.  * Function:    domove
  3087.  *        
  3088.  * Description:    Play a move on board b[][] at (x,y), perform any capturing and
  3089.  *        illegal move checking necessary.
  3090.  *        If x and y are both 0, this is treated as a 'pass'.
  3091.  *        Return a boolean indicating whether it was a legal move or not.
  3092.  *        
  3093.  * Globals affected:    captured, checking, komove
  3094.  *            
  3095.  */
  3096. BOOLEAN
  3097. domove(x,y,b)
  3098. COORD x,y ;
  3099. MOVENUMBER b[MAX][MAX] ;
  3100. {
  3101. COLOUR thisstonecolour, oppositecolour ;
  3102. POSTYPE thispos ;
  3103. BOOLEAN legalmove ;
  3104.  
  3105.     if ( (x==0) && (y==0) )
  3106.     {
  3107.         passmove() ;
  3108.         legalmove = TRUE ;
  3109.     }
  3110.     else
  3111.     {
  3112.         /* Basic checks */
  3113.         if ( (b[x][y]!=0) ||    /* can't play on top of another stone */
  3114.              (x<1)        ||    /* out of range */
  3115.              (x>size)     ||
  3116.              (y<1)        ||
  3117.              (y>size)       )
  3118.         {
  3119.             clearpromptline() ;
  3120.             displaystring("Must play on one of the vacant points") ;
  3121.             legalmove = FALSE ;
  3122.         }
  3123.  
  3124.         else
  3125.         {
  3126.  
  3127.             if (flag[PRACTICE]==off)
  3128.             {
  3129.                 thisstonecolour = stonecolour(currentmove) ;
  3130.             }
  3131.             else
  3132.             {
  3133.                 if (nextpracticestone==black)
  3134.                 {
  3135.                         thisstonecolour = black ;
  3136.                 }
  3137.                 else
  3138.                 {
  3139.                         thisstonecolour = white ;
  3140.                 }
  3141.             }
  3142.  
  3143.     
  3144.             if (thisstonecolour==black)
  3145.                 oppositecolour = white ;
  3146.             else
  3147.                 oppositecolour = black ;
  3148.     
  3149.             saveboard() ;
  3150.             b[x][y] = thisstonecolour ; /*put the stone in temporarily*/
  3151.     
  3152.             captured = 0 ;
  3153.             checking = 0 ;
  3154.     
  3155.             thispos = postype(x,y) ;
  3156.  
  3157.             /* See if any opponents' stones have been captured */
  3158.     
  3159.             switch((int)thispos)
  3160.             {
  3161.                 case topleft :    docheck(x+1,y,b,oppositecolour);
  3162.                         docheck(x,y+1,b,oppositecolour);
  3163.                         break ;
  3164.  
  3165.                 case topside :    docheck(x+1,y,b,oppositecolour);
  3166.                         docheck(x-1,y,b,oppositecolour);
  3167.                         docheck(x,y+1,b,oppositecolour);
  3168.                         break ;
  3169.     
  3170.                 case topright :    docheck(x-1,y,b,oppositecolour);
  3171.                         docheck(x,y+1,b,oppositecolour);
  3172.                         break ;
  3173.     
  3174.                 case rightside:    docheck(x-1,y,b,oppositecolour);
  3175.                         docheck(x,y+1,b,oppositecolour);
  3176.                         docheck(x,y-1,b,oppositecolour);
  3177.                         break ;
  3178.     
  3179.                 case middle :    docheck(x+1,y,b,oppositecolour);
  3180.                         docheck(x-1,y,b,oppositecolour);
  3181.                         docheck(x,y+1,b,oppositecolour);
  3182.                         docheck(x,y-1,b,oppositecolour);
  3183.                         break ;
  3184.     
  3185.                 case leftside :    docheck(x+1,y,b,oppositecolour);
  3186.                         docheck(x,y+1,b,oppositecolour);
  3187.                         docheck(x,y-1,b,oppositecolour);
  3188.                         break ;
  3189.     
  3190.                 case bottomleft:docheck(x+1,y,b,oppositecolour);
  3191.                         docheck(x,y-1,b,oppositecolour);
  3192.                         break ;
  3193.     
  3194.                 case bottomside:docheck(x+1,y,b,oppositecolour);
  3195.                         docheck(x-1,y,b,oppositecolour);
  3196.                         docheck(x,y-1,b,oppositecolour);
  3197.                         break ;
  3198.     
  3199.                 case bottomright:docheck(x-1,y,b,oppositecolour);
  3200.                         docheck(x,y-1,b,oppositecolour);
  3201.                         break ;
  3202.  
  3203.                 default :    errorprint("Illegal postype in domove()");
  3204.                         break ;
  3205.     
  3206.             } /* end switch */
  3207.  
  3208.             if (captured==0)
  3209.             {
  3210.                 /* No opponents' stones taken so check the
  3211.                  * group formed by this move to see if it 
  3212.                  * is dead.
  3213.                  */
  3214.                 docheck(x,y,b,thisstonecolour) ;
  3215.     
  3216.                 if (captured==0)
  3217.                 {
  3218.                     playstone(x,y,b) ;
  3219.                     komove.x = 0 ;
  3220.                     komove.y = 0 ;
  3221.                     legalmove = TRUE ;
  3222.                 }
  3223.                 else
  3224.                 {
  3225.                     clearpromptline() ;
  3226.                     displaystring("Cannot play a suicidal move") ;
  3227.                     /* suicidal move */
  3228.                     legalmove = FALSE ;
  3229.                     b[x][y] = 0 ;
  3230.                 }
  3231.             }
  3232.             else if (captured==1)
  3233.                 {
  3234.                     /* Simplistic Ko Algorithm:
  3235.                      * If last move only took one stone
  3236.                      * and this move is in the same
  3237.                      * position and it only takes one
  3238.                      * then this is ko.
  3239.                      */
  3240.                     if ( (komove.x==x) &&
  3241.                          (komove.y==y) )
  3242.                     {
  3243.                         /* ko */
  3244.                         clearpromptline() ;
  3245.                         displaystring("Must play elsewhere first before re-taking : the rule of ko") ;
  3246.                         b[x][y] = 0 ;
  3247.                         legalmove = FALSE ;
  3248.                     }
  3249.                     else
  3250.                     {
  3251.                         komove.x = deadstones[1].x ;
  3252.                         komove.y = deadstones[1].y ;
  3253.                         playstone(x,y,b) ;
  3254.                         removecaptured(b) ;
  3255.  
  3256.                         if (flag[PRACTICE]==off)
  3257.                         {
  3258.                             if (oppositecolour==black)
  3259.                                 blackcaptured += captured ;
  3260.                             else
  3261.                                 whitecaptured += captured ;
  3262.                             displaycaptured() ;
  3263.                         }
  3264.  
  3265.                         legalmove = TRUE ;
  3266.                     }
  3267.                 } /* end if captured = 1 */
  3268.                 else
  3269.                 {
  3270.                     playstone(x,y,b) ;
  3271.                     removecaptured(b) ;
  3272.  
  3273.                     if (flag[PRACTICE]==off)
  3274.                     {
  3275.                         if (oppositecolour==black)
  3276.                             blackcaptured += captured ;
  3277.                         else
  3278.                             whitecaptured += captured ;
  3279.                         displaycaptured() ;
  3280.                     }
  3281.  
  3282.                     komove.x = 0 ;
  3283.                     komove.y = 0 ;
  3284.                     legalmove = TRUE ;
  3285.                 } /* end if captured > 1 */
  3286.  
  3287.         } /* end if basic checks */
  3288.  
  3289.     } /* end if pass */
  3290.  
  3291.     return(legalmove) ;
  3292. }
  3293.  
  3294. /*
  3295.  * Function:    translateascii
  3296.  *        
  3297.  * Description:    Translate the character passed which represents the East-West
  3298.  *        grid reference into the index 1 to 19, return this value.
  3299.  *        
  3300.  *        
  3301.  * Globals affected:    none
  3302.  *            
  3303.  */
  3304. char
  3305. translateascii(c)
  3306. char c ;
  3307. {
  3308. char retval ;
  3309.  
  3310.     if ( (c>='a') && (c<='h') )
  3311.     {
  3312.         retval = c-'a'+1 ;
  3313.     }
  3314.  
  3315.     if (c=='i') retval=0;
  3316.  
  3317.     if ( (c>='j') && (c<='t') )
  3318.     {
  3319.         retval = c-'a' ;
  3320.     }
  3321.  
  3322.     if ( (c>='A') && (c<='H') )
  3323.     {
  3324.         retval = c-'A'+1 ;
  3325.     }
  3326.  
  3327.     if (c=='I') retval=0;
  3328.  
  3329.     if ( (c>='J') && (c<='T') )
  3330.     {
  3331.         retval = c-'A' ;
  3332.     }
  3333.  
  3334.  
  3335.     return(retval) ;
  3336. }
  3337.  
  3338. /*
  3339.  * Function:    translateraw
  3340.  *        
  3341.  * Description:    Return a value indicating what sort of 'text' was in the
  3342.  *        raw line passed as a parameter, returns a string and/or values
  3343.  *        found in the raw line if necessary eg newgame means x will
  3344.  *        be the size, y will be the handicap and s will have any 
  3345.  *        comment that accompanies the new game.
  3346.  *        nullraw may or may not have text associated with it.
  3347.  *        
  3348.  * Globals affected:    none
  3349.  *            
  3350.  */
  3351. RAWTYPE
  3352. translateraw (r,x,y,s,skip)
  3353. char *r,*s ; /* r is a pointer to the raw string */
  3354.         /* s is a pointer to returned text */
  3355. char *x,*y ;    /* x and y are retruned values */
  3356. BOOLEAN *skip ;
  3357. {
  3358.  
  3359.  
  3360. /* Table of character collecting states                                     */
  3361. /* The number shown in th etable represents the next collecting state       */
  3362. /* WS=white space, E=error, X=exit                                          */
  3363.             /*    Alpha    Numeric    WS    '!'    '|'    '#' */
  3364. #define    COLLECTING 0    /*    5    1    0    4    X    3   */
  3365. #define SIZE 1        /*    E    1    2    E    E    E   */
  3366. #define    HANDICAP 2    /*    E    2    2    E    X    3   */
  3367. #define COMMENT 3    /*    3    3    3    3    X    3   */
  3368. #define CONTROL 4    /*    4    4    X    4    4    4   */
  3369. #define XMOVE 5        /*    E    6    6    E    E    E   */
  3370. #define YMOVE 6        /*    E    6    6    E    X    3   */
  3371.  
  3372. int index ;    /* index into r */
  3373. RAWTYPE retval ;
  3374. BOOLEAN oktoexit ;
  3375. unsigned char state ;
  3376. int count ;    /* number of chars in s already */
  3377. int n ;        /* used for building up decimal numbers */
  3378.  
  3379.     *s = 0 ;
  3380.     retval = nullraw ;
  3381.     oktoexit = FALSE ;
  3382.     index = 0 ;
  3383.  
  3384.     *x = 0 ;
  3385.     *y = 0 ;
  3386.  
  3387.     *skip = FALSE ;
  3388.  
  3389.     state = COLLECTING ;
  3390.  
  3391.     while ( (r[index]!=0) && (!oktoexit) )
  3392.     {
  3393.         /* first check for the 'pass' string */
  3394.         if ( (strncmp(&r[index],"pass",4)==0) &&
  3395.              (retval==nullraw) &&
  3396.              (state==COLLECTING) )
  3397.         {
  3398.             *x = 0 ;
  3399.             *y = 0 ;
  3400.             retval = amove ;
  3401.             index += 4 ;
  3402.         }
  3403.  
  3404.         switch (r[index])
  3405.         {
  3406.             case ' ' :
  3407.             case '\t' :
  3408.             case '\n' :
  3409.                 switch (state)
  3410.                 {
  3411.                     case COLLECTING :
  3412.                         break ;
  3413.                     case SIZE :
  3414.                         state = HANDICAP ;
  3415.                         *x = n ;
  3416.                         n = 0 ;
  3417.                         break ;
  3418.                     case HANDICAP :
  3419.                         break ;
  3420.                     case COMMENT :
  3421.                         s[count++] = r[index] ;    
  3422.                         break ;
  3423.                     case CONTROL :
  3424.                         oktoexit = TRUE ;
  3425.                         retval = control ;
  3426.                         *skip = TRUE ;
  3427.                         break ;
  3428.                     case XMOVE :
  3429.                         state = YMOVE ;
  3430.                         n = 0 ;
  3431.                         break ;
  3432.                     case YMOVE :
  3433.                         break ;
  3434.                     default : break ;
  3435.                 }
  3436.                 break ;
  3437.  
  3438.             case '!' :
  3439.                 switch (state)
  3440.                 {
  3441.                     case COLLECTING :
  3442.                         count = 0 ;
  3443.                         state = CONTROL ;
  3444.                         break ;
  3445.                     case SIZE :
  3446.                         retval = rawerror ;
  3447.                         oktoexit = TRUE ;
  3448.                         break ;
  3449.                     case HANDICAP :
  3450.                         retval = rawerror ;
  3451.                         oktoexit = TRUE ;
  3452.                         break ;
  3453.                     case COMMENT :
  3454.                         s[count++] = r[index] ;    
  3455.                         break ;
  3456.                     case CONTROL :
  3457.                         s[count++] = r[index] ;
  3458.                         break ;
  3459.                     case XMOVE :
  3460.                         retval = rawerror ;
  3461.                         oktoexit = TRUE ;
  3462.                         break ;
  3463.                     case YMOVE :
  3464.                         retval = rawerror ;
  3465.                         oktoexit = TRUE ;
  3466.                         break ;
  3467.                     default : break ;
  3468.                 }
  3469.                 break ;
  3470.  
  3471.             case '|' :
  3472.                 switch (state)
  3473.                 {
  3474.                     case COLLECTING :
  3475.                         oktoexit = TRUE ;
  3476.                         *skip = TRUE ;
  3477.                         break ;
  3478.                     case SIZE :
  3479.                         retval = rawerror ;
  3480.                         oktoexit = TRUE ;
  3481.                         break ;
  3482.                     case HANDICAP :
  3483.                         retval = newgame ;
  3484.                         oktoexit = TRUE ;
  3485.                         *skip = TRUE ;
  3486.                         *y = n ;
  3487.                         break ;
  3488.                     case COMMENT :
  3489.                         oktoexit = TRUE ;
  3490.                         *skip = TRUE ;
  3491.                         break ;
  3492.                     case CONTROL :
  3493.                         s[count++] = r[index] ;
  3494.                         break ;
  3495.                     case XMOVE :
  3496.                         retval = rawerror ;
  3497.                         oktoexit = TRUE ;
  3498.                         break ;
  3499.                     case YMOVE :
  3500.                         retval = amove ;
  3501.                         *y = size - n + 1 ;
  3502.                         oktoexit = TRUE ;
  3503.                         *skip = TRUE ;
  3504.                         break ;
  3505.                     default : break ;
  3506.                 }
  3507.                 break ;
  3508.  
  3509.             case '#' :
  3510.                 switch (state)
  3511.                 {
  3512.                     case COLLECTING :
  3513.                         count = 0 ;
  3514.                         state = COMMENT ;
  3515.                         break ;
  3516.                     case SIZE :
  3517.                         retval = rawerror ;
  3518.                         oktoexit = TRUE ;
  3519.                         break ;
  3520.                     case HANDICAP :
  3521.                         count = 0 ;
  3522.                         retval = newgame ;
  3523.                         state = COMMENT ;
  3524.                         *y = n ;
  3525.                         break ;
  3526.                     case COMMENT :
  3527.                         s[count++] = r[index] ;
  3528.                         break ;
  3529.                     case CONTROL :
  3530.                         s[count++] = r[index] ;
  3531.                         break ;
  3532.                     case XMOVE :
  3533.                         retval = rawerror ;
  3534.                         oktoexit = TRUE ;
  3535.                         break ;
  3536.                     case YMOVE :
  3537.                         count = 0 ;
  3538.                         retval = amove ;
  3539.                         *y = size - n + 1 ;
  3540.                         state = COMMENT ;
  3541.                         break ;
  3542.                     default : break ;
  3543.                 }
  3544.                 break ;
  3545.  
  3546.         default :
  3547.             if ( r[index]>='0' && r[index]<='9' )
  3548.                 switch (state)
  3549.                 {
  3550.                     case COLLECTING :
  3551.                         state = SIZE ;
  3552.                         n = r[index] - '0' ;
  3553.                         break ;
  3554.                     case SIZE :
  3555.                         n = n*10 + r[index] - '0' ;
  3556.                         break ;
  3557.                     case HANDICAP :
  3558.                         n = r[index] - '0' ;
  3559.                         break ;
  3560.                     case COMMENT :
  3561.                         s[count++] = r[index] ;
  3562.                         break ;
  3563.                     case CONTROL :
  3564.                         s[count++] = r[index] ;
  3565.                         break ;
  3566.                     case XMOVE :
  3567.                         state = YMOVE ;
  3568.                         n = r[index] - '0' ;
  3569.                         break ;
  3570.                     case YMOVE :
  3571.                         n = n*10 + r[index] - '0' ;
  3572.                         break ;
  3573.                     default : break ;
  3574.                 }
  3575.             else
  3576.                 switch (state)
  3577.                 {
  3578.                     case COLLECTING :
  3579.                         if ( ( r[index]>='a' && r[index]<='z' ) ||
  3580.                                  ( r[index]>='A' && r[index]<='Z' ) )
  3581.                         {
  3582.                             state = XMOVE ;
  3583.                             *x = translateascii(r[index]) ;
  3584.                         }
  3585.                         break ;
  3586.                     case SIZE :
  3587.                         retval = rawerror ;
  3588.                         oktoexit = TRUE ;
  3589.                         break ;
  3590.                     case HANDICAP :
  3591.                         retval = rawerror ;
  3592.                         oktoexit = TRUE ;
  3593.                         break ;
  3594.                     case COMMENT :
  3595.                         s[count++] = r[index] ;
  3596.                         break ;
  3597.                     case CONTROL :
  3598.                         s[count++] = r[index] ;
  3599.                         break ;
  3600.                     case XMOVE :
  3601.                         retval = rawerror ;
  3602.                         oktoexit = TRUE ;
  3603.                         break ;
  3604.                     case YMOVE :
  3605.                         retval = rawerror ;
  3606.                         oktoexit = TRUE ;
  3607.                         break ;
  3608.                     default : break ;
  3609.                 }
  3610.             break ;
  3611.             
  3612.  
  3613.         } /* end switch on r[index] */
  3614.  
  3615.         index++ ;
  3616.     }
  3617.  
  3618.  
  3619.     if ( retval != rawerror)
  3620.     {
  3621.  
  3622.         if ( state==SIZE || state==XMOVE)
  3623.             retval = rawerror ;
  3624.  
  3625.         if ( state==HANDICAP )  
  3626.         {
  3627.             *y = n ;
  3628.             retval = newgame ;
  3629.         }
  3630.     
  3631.         if ( state==YMOVE ) 
  3632.         {
  3633.             *y = size - n + 1 ;
  3634.             retval = amove ;
  3635.         }
  3636.  
  3637.         if ( state==COMMENT || state==CONTROL )
  3638.             s[count] = 0 ;
  3639.  
  3640.         /* skip over any blank lines in the input */
  3641.         if ( (retval==nullraw) && (s[0]==0) ) 
  3642.             *skip = TRUE ;
  3643.     }
  3644.  
  3645.     return(retval) ;
  3646. }
  3647.  
  3648. /*
  3649.  * Function:    errorat()
  3650.  *        
  3651.  * Description:    The file read in contains an error at line n, display
  3652.  *        the appropriate message.
  3653.  *        
  3654.  * Globals affected:    none
  3655.  *            
  3656.  */
  3657.  
  3658. errorat( msg, n )
  3659. char msg[MAXLINELENGTH] ;
  3660. int n ;
  3661. {
  3662. char str[3] ;
  3663. char total[MAXLINELENGTH+3] ;
  3664.  
  3665.  
  3666.     str[0] = '\0' ;
  3667.     sprintf( str, "%d", n ) ;
  3668.  
  3669.     total[0] = 0 ;
  3670.     strcat( total, msg ) ;
  3671.     strcat( total, str ) ;
  3672.  
  3673.     errorprint( total ) ;
  3674. }
  3675.  
  3676. /*
  3677.  * Function:    readline()
  3678.  *        
  3679.  * Description:    Reads in a line from file pointed to by fptr,
  3680.  *        allocates the memory in store it and then copies the
  3681.  *        line into raw[].
  3682.  *
  3683.  *        If EOF or no memory left then returns FALSE.
  3684.  *
  3685.  *        Is responsible for printing an error message if one happens
  3686.  *
  3687.  * Globals affected:    raw[], rawindex
  3688.  *            
  3689.  */
  3690. BOOLEAN
  3691. readline()
  3692. {
  3693. char line[MAXLINELENGTH] ;
  3694. BOOLEAN retval ;
  3695.  
  3696.     retval = TRUE ;
  3697.  
  3698.     if (rawindex==MAXRAW)
  3699.     {
  3700.         errorprint("raw buffer full") ;
  3701.         retval = FALSE ;
  3702.     }
  3703.     else
  3704.     {
  3705.  
  3706.         if ( fgets( line, MAXLINELENGTH, fptr ) != NULL ) 
  3707.         {
  3708.         /* fgets reads up to MAXLINELENGTH-1 and if it hasnt found a
  3709.          * newline puts a '\0' at MAXLINELENGTH position.
  3710.          * (fgets leaves the newline at the end of a string)
  3711.          */
  3712.  
  3713.             if ( ( strlen(line)==MAXLINELENGTH-1) &&
  3714.                  ( line[MAXLINELENGTH-2]!='\n') )
  3715.             {
  3716.                 errorat("Input exceeds '80 char + newline' limit at line ", rawindex+1 ) ;
  3717.                 retval = FALSE ;
  3718.             }
  3719.  
  3720.             raw[rawindex] = malloc((unsigned)strlen(line)) ;
  3721.  
  3722.             if (raw[rawindex]==NULL)
  3723.             {
  3724.                 errorprint("No memory") ;
  3725.                 retval = FALSE ;
  3726.             }
  3727.             else
  3728.             {
  3729.                 strcpy( raw[rawindex], line ) ;
  3730.                 rawindex++ ;
  3731.             }
  3732.         }
  3733.         else
  3734.         {
  3735.             /* EOF */
  3736.             retval = FALSE ;
  3737.         }
  3738.     }
  3739.  
  3740.     return(retval) ;
  3741. }
  3742.  
  3743. /*
  3744.  * Function:    toggleflag
  3745.  *        
  3746.  * Description:    
  3747.  *        
  3748.  *        
  3749.  *        
  3750.  * Globals affected:    flag[]
  3751.  *            
  3752.  */
  3753. void
  3754. toggleflag(f)
  3755. char f ;
  3756. {
  3757.     if (flag[f]==off)
  3758.         flag[f]=on ;
  3759.     else
  3760.         flag[f]=off ;
  3761.  
  3762.     refreshmenu() ;
  3763. }
  3764.  
  3765. /*
  3766.  * Function:    docontrol
  3767.  *        
  3768.  * Description:    Perform the control specified in the string passed as a 
  3769.  *        parameter
  3770.  *        
  3771.  *        
  3772.  * Globals affected:    none
  3773.  *            
  3774.  */
  3775. void
  3776. docontrol(str)
  3777. char *str ;
  3778. {
  3779.     if ( strcmp(str,"numbers") == 0 )
  3780.     {
  3781.         toggleflag(NUMBERS) ;
  3782.     }
  3783.  
  3784.     if ( strcmp(str,"grid") == 0 )
  3785.     {
  3786.         toggleflag(GRID) ;
  3787.     }
  3788.  
  3789.     if ( strcmp( str, "lastmove" ) == 0 )
  3790.     {
  3791.         toggleflag(LASTMOVE) ;
  3792.     }
  3793.  
  3794.     if ( strcmp(str,"clear") == 0 )
  3795.     {
  3796.         erasescreen() ;
  3797.     }
  3798. }
  3799.  
  3800. /*
  3801.  * Function:    translateline
  3802.  *        
  3803.  * Description:    Performs the actions specified in the text of str,
  3804.  *        returns TRUE if if the line contained a legal move.
  3805.  *        
  3806.  * Globals affected:    size, handicap, currentmove
  3807.  *            
  3808.  */
  3809. BOOLEAN
  3810. translateline(str,text,skip)
  3811. char *str ;
  3812. char text[MAXLINELENGTH] ;
  3813. BOOLEAN *skip ;
  3814. {
  3815. char x,y ;
  3816.  
  3817. BOOLEAN ret_val ;
  3818.  
  3819.     ret_val = TRUE ;
  3820.  
  3821.  
  3822.  
  3823.     switch((int)translateraw(str,&x,&y,text,skip))
  3824.     {
  3825.         case amove:    if (flag[PRACTICE]==off)
  3826.                     ret_val = domove((COORD)x,(COORD)y,realboard) ;
  3827.                 else
  3828.                     ret_val = domove((COORD)x,(COORD)y,practiceboard) ;
  3829.                 break ;
  3830.  
  3831.         case newgame:    resetgame(x,y) ;
  3832.                 ret_val = TRUE ;
  3833.                 break ;
  3834.  
  3835.         case control:    docontrol(text) ;
  3836.                 ret_val = TRUE ;
  3837.                 text[0] = 0 ; /* zero the text so that it
  3838.                            * doesn't get mistaken for
  3839.                            * a comment in readastep()
  3840.                            */
  3841.                 break ;
  3842.  
  3843.         case nullraw :    break ;
  3844.  
  3845.         case rawerror :    ret_val = FALSE ;
  3846.                 break ;
  3847.  
  3848.         default:    errorprint("translateline error") ;
  3849.                 ret_val = FALSE ;
  3850.                 break ;
  3851.     }
  3852.  
  3853.     return(ret_val); 
  3854. }
  3855.  
  3856. /*
  3857.  * Function:    readin
  3858.  *        
  3859.  * Description:    Reads in a whole file, performing the moves.
  3860.  *        
  3861.  *        
  3862.  * Globals affected:    writeindex
  3863.  *            
  3864.  */
  3865. readin(fn)
  3866. char fn[] ;
  3867. {
  3868. char text[MAXLINELENGTH] ;
  3869. BOOLEAN skip ;
  3870. BOOLEAN line_ok ;
  3871.  
  3872.     rawindex = 0 ;
  3873.     writeindex = 0 ;
  3874.  
  3875.     fptr = fopen(directoryplus(fn),"r") ;
  3876.     if (fptr==(FILE *)NULL)
  3877.     {
  3878.         errorprint("unable to open file") ;
  3879.         return ;
  3880.     }
  3881.  
  3882.     initialiseflags() ;
  3883.  
  3884.     displaystring("reading") ;
  3885.  
  3886.     line_ok = TRUE ;
  3887.  
  3888.     while ( readline()==TRUE && line_ok==TRUE )
  3889.     {
  3890.         line_ok = translateline( raw[rawindex-1], text, &skip ) ;
  3891.     }
  3892.  
  3893.     if ( line_ok != TRUE )
  3894.         errorat( ILLEGALAT, rawindex ) ;
  3895.  
  3896.  
  3897.     writeindex = rawindex ;
  3898.  
  3899.     fclose(fptr) ;
  3900.  
  3901.     clearpromptline() ;
  3902.     
  3903. }
  3904.  
  3905. /*
  3906.  * Function:    stripnewline()
  3907.  *        
  3908.  * Description:    If there is a newline char '\n' at the end of s then replace
  3909.  *        it with a null '\0'
  3910.  *        
  3911.  *        
  3912.  * Globals affected:    none
  3913.  *            
  3914.  */
  3915. stripnewline(s)
  3916. char s[] ;
  3917. {
  3918.     if (s[strlen(s)-1]=='\n')
  3919.         s[strlen(s)-1] = '\0' ;
  3920. }
  3921.  
  3922. /*
  3923.  * Function:    gotoaline()
  3924.  *        
  3925.  * Description:    String passed is the index into raw[] that the player
  3926.  *        wishes to end up at.
  3927.  *        
  3928.  *        
  3929.  * Globals affected:    
  3930.  *            
  3931.  */
  3932. void
  3933. gotoaline(s)
  3934. char s[MAXLINELENGTH] ;
  3935. {
  3936. MOVENUMBER n ;
  3937. char text[MAXLINELENGTH] ;
  3938. BOOLEAN skip ;
  3939.  
  3940.     n = (MOVENUMBER)atoi(s) ;
  3941.  
  3942.     if ( ( n != steppingindex ) && ( n != 0 ) )
  3943.     {
  3944.         if ( n < (steppingindex+1) )
  3945.             steppingindex = 0 ;
  3946.  
  3947.         while ( ( steppingindex < rawindex ) &&
  3948.             ( steppingindex < n ) )
  3949.         {
  3950.             (void)translateline(raw[steppingindex], 
  3951.                         text,
  3952.                         &skip) ;
  3953.             steppingindex++ ;
  3954.             refreshmenu() ;
  3955.         }
  3956.     }
  3957.     
  3958. }
  3959.  
  3960. /*
  3961.  * Function:    gotoamove
  3962.  *        
  3963.  * Description:    Re-reads a file stored in raw[], performing the moves up to
  3964.  *        a move number or move specified  in the parameter.
  3965.  *        
  3966.  *        
  3967.  * Globals affected:    currentmove, steppingindex
  3968.  *            
  3969.  */
  3970. gotoamove(s)
  3971. char s[MAXLINELENGTH] ;
  3972. {
  3973. int indx ;
  3974. char text[MAXLINELENGTH] ;
  3975. BOOLEAN skip ;
  3976. char x,y ;
  3977.  
  3978.     /* Use translateraw() to decide whether the parameter is a movenumber
  3979.      * or an actual move, (using 'newgame' is a dirty trick but it works)
  3980.      */
  3981.  
  3982.     switch( (int)translateraw( s, &x, &y, text, &skip ) )
  3983.     {
  3984.         case amove :
  3985.             stripnewline(s) ;
  3986.  
  3987.             /* If the first is a space or a tab (the
  3988.              * only allowable white spaces) then shift it down
  3989.              */
  3990.             if (s[0]==' ' || s[0]=='\t')
  3991.             {
  3992.                 for (indx=0 ; indx<=strlen(s) ; indx++ )
  3993.                     s[indx] = s[indx+1] ;
  3994.             }
  3995.  
  3996.             /* convert the ascii letter in the coordinates
  3997.              * to upper case, this works even if it is already
  3998.              * in upper case.
  3999.              */
  4000.             s[0] ^= 0x20 ;
  4001.  
  4002.             steppingindex = lastreconfigure ;
  4003.  
  4004.             while ( ( steppingindex < rawindex ) &&
  4005.                 ( strcmp(lastmovestring,s)!=0 ) )
  4006.             {
  4007.                 (void)translateline(raw[steppingindex], text, &skip) ;
  4008.                 steppingindex++ ;
  4009.             }
  4010.             break ;
  4011.  
  4012.         case newgame :
  4013.             /* ie goto a move number, x is the move number */
  4014.  
  4015.             if ( x < currentmove )
  4016.                 steppingindex = lastreconfigure ;
  4017.  
  4018.             if ( x != currentmove )
  4019.             {
  4020.                 do
  4021.                 {
  4022.                     (void)translateline(raw[steppingindex], 
  4023.                                 text,
  4024.                                 &skip) ;
  4025.                     steppingindex++ ;
  4026.                 }
  4027.                 while ( ( steppingindex < rawindex ) &&
  4028.                     ( currentmove <= x ) ) ;
  4029.             }
  4030.             break ;
  4031.  
  4032.         default :
  4033.             /* ignore errors as player may just have made a
  4034.              * mistake in requesting goto
  4035.              */
  4036.             break ;
  4037.  
  4038.     }
  4039.  
  4040. }
  4041.  
  4042. /*
  4043.  * Function:    readastep()
  4044.  *        
  4045.  * Description:    Translate the next line in raw[], performs the action and
  4046.  *        displays any comment that goes with the text.
  4047.  *        If the text was a 'skip' then continue reading until the
  4048.  *        next non skip.
  4049.  *        
  4050.  * Globals affected:    size, handicap, currentmove, steppingindex
  4051.  *            
  4052.  */
  4053. void
  4054. readastep()
  4055. {
  4056.  
  4057. char text[MAXLINELENGTH] ;
  4058. BOOLEAN skip ;
  4059. BOOLEAN line_ok ;
  4060.  
  4061.     if (steppingindex>=rawindex)
  4062.     {
  4063.         clearpromptline() ;
  4064.         displaystring("End of file") ;
  4065.     }
  4066.     else
  4067.     {
  4068.  
  4069.         skip = TRUE ;
  4070.  
  4071.         line_ok = TRUE ;
  4072.  
  4073.         while ( ( skip ) && ( steppingindex < rawindex ) )
  4074.         {
  4075.             line_ok = translateline(raw[steppingindex],text,&skip) ;
  4076.     
  4077.             if (line_ok==TRUE)
  4078.             {
  4079.                 if (text[0]!=0)
  4080.                 {
  4081.                     clearpromptline() ;
  4082.                     displaystring(text) ;
  4083.                 }
  4084.             }
  4085.             else
  4086.             {
  4087.                 errorat( ILLEGALAT, steppingindex+1 ) ;
  4088.             }
  4089.     
  4090.             steppingindex++ ;
  4091.             refreshmenu() ;
  4092.         
  4093.         } /* end while */
  4094.  
  4095.     }
  4096.  
  4097. }
  4098.  
  4099. /*
  4100.  * Function:    startstepping()
  4101.  *        
  4102.  * Description:    Prompts the player for a file name, if it is the same as
  4103.  *        the one read in (ie text is already in raw[]) then proceed to
  4104.  *        perform the first step, else read in the whole file into
  4105.  *        raw[] without translating it, then perform the first step.
  4106.  *        
  4107.  * Globals affected:    rawindex, raw[], steppinindex, flag[STEPPING]
  4108.  *            
  4109.  */
  4110. startstepping()
  4111. {
  4112.  
  4113.     filename[0] = 0 ;
  4114.  
  4115.     getfilename(tempfilename) ;
  4116.  
  4117.     if ( tempfilename[0]!=0 )
  4118.     {
  4119.         fptr = fopen(directoryplus(tempfilename),"r") ;
  4120.         if (fptr==(FILE *)NULL)
  4121.         {
  4122.             errorprint("unable to open file") ;
  4123.         }
  4124.         else
  4125.         {
  4126.             initialiseflags() ;
  4127.  
  4128.             rawindex = 0 ;
  4129.  
  4130.             displaystring("reading") ;
  4131.  
  4132.             while ( readline() == TRUE ) ;
  4133.  
  4134.             fclose(fptr) ;
  4135.  
  4136.             clearpromptline() ;
  4137.  
  4138.             steppingindex = 0 ;
  4139.             flag[STEPPING] = on ;
  4140.             refreshmenu() ;
  4141.             readastep() ;
  4142.         }
  4143.     }
  4144. }
  4145.  
  4146. /*
  4147.  * Function:    setstonecolour
  4148.  *        
  4149.  * Description:    This determines what value the colours black and white will
  4150.  *        have. If there is no handicap then white will be even move
  4151.  *        numbers and black odd, else the other way around.
  4152.  *        
  4153.  * Globals affected:    none
  4154.  *            
  4155.  */
  4156. setstonecolour()
  4157. {
  4158.     if (handicap==0)
  4159.     {
  4160.         black = 1 ;
  4161.         white = 2 ;
  4162.     }
  4163.     else
  4164.     {
  4165.         black = 2 ;
  4166.         white = 1 ;
  4167.     }
  4168. }
  4169.  
  4170. /*
  4171.  * Function:    removedifferences
  4172.  *        
  4173.  * Description:    Restores old board to look like new board
  4174.  *        
  4175.  *        
  4176.  * Globals affected:    none
  4177.  *            
  4178.  */
  4179. removedifferences(old,new)
  4180. MOVENUMBER old[MAX][MAX] ;
  4181. MOVENUMBER new[MAX][MAX] ;
  4182. {
  4183. COORD i,j ;
  4184.  
  4185.     for (i=1;i<=size;i++)
  4186.         for (j=1;j<=size;j++)
  4187.             if (old[i][j]!=new[i][j])
  4188.             {
  4189.                 placestone(i,j,new[i][j]) ;
  4190.                 old[i][j] = new[i][j] ;
  4191.             }
  4192. }
  4193.  
  4194. /*
  4195.  * Function:    convertandstore
  4196.  *        
  4197.  * Description:    Converts the move passed in 'internal format' into a string
  4198.  *        and stores in it raw[]
  4199.  *        
  4200.  *        
  4201.  * Globals affected:    none
  4202.  *            
  4203.  */
  4204. convertandstore(x,y)
  4205. COORD x,y ;
  4206. {
  4207. char str[6] ;
  4208.  
  4209.     converttostring( x, y, str ) ;
  4210.  
  4211.     strcat( str, "\n") ;
  4212.  
  4213.     store( str ) ;
  4214. }
  4215.  
  4216. /*
  4217.  * Function:    converttostring
  4218.  *        
  4219.  * Description:    Converts the move in (x,y) coordinates into its raw
  4220.  *        text, eg (2,3) is "B7" on a 9x9 board.
  4221.  *        
  4222.  *        Convention: "translation" is from raw text to program
  4223.  *        understandable data, "conversion" is the other way around.
  4224.  *        
  4225.  * Globals affected:    none
  4226.  *            
  4227.  */
  4228. converttostring(x,y,str)
  4229. COORD x,y ;
  4230. char str[] ;
  4231. {
  4232. COORD temp ;
  4233. char tempstr[3] ;
  4234.  
  4235.     str[0] = 0 ;
  4236.  
  4237.     if (x==0 && y==0)
  4238.         strcpy(str,"pass") ;
  4239.     else
  4240.     {
  4241.         if (x<=8)
  4242.         {
  4243.             str[0]= x + 'A' - 1 ;
  4244.         }
  4245.         else
  4246.         {
  4247.             str[0] = x + 'J' - 9 ;
  4248.         }
  4249.     
  4250.         str[1] = 0 ;
  4251.         temp = size - y + 1 ; /* numbering down */
  4252.         sprintf(tempstr,"%d",temp) ;
  4253.         strcat(str,tempstr) ;
  4254.     
  4255.     }
  4256. }
  4257.  
  4258. void
  4259. main(argc,argv)
  4260. int argc ;
  4261. char *argv[] ;
  4262. {
  4263. ACTIONTYPE action ;
  4264. char   actbuffer[MAXLINELENGTH] ;
  4265. BOOLEAN oktoexit ;
  4266. BOOLEAN legalmove ;
  4267. char text[MAXLINELENGTH] ;
  4268. BOOLEAN skip ;
  4269. int indx ;
  4270.  
  4271.  
  4272.     startterminalspecific(argc,argv) ;
  4273.  
  4274.  
  4275.     currentmove = 1 ;
  4276.  
  4277.  
  4278.     filename[0] = 0  ;
  4279.     rawindex = 0 ; /* dont put in zeroboard */
  4280.  
  4281.     zeroboard() ;
  4282.  
  4283.     erasescreen() ;
  4284.  
  4285.     flag[PRACTICE] = off ;
  4286.     flag[STEPPING] = off ;
  4287.     refreshmenu() ;
  4288.  
  4289.     /* Get the parameters */
  4290.  
  4291.     for (indx=1 ; indx<argc ; indx++)
  4292.     {
  4293.         if (strcmp("-d",argv[indx]) == 0 )
  4294.         {
  4295.             indx++ ;
  4296.             strcpy(directory,argv[indx]) ;
  4297.         }
  4298.  
  4299.         if (strcmp("-r",argv[indx]) == 0 )
  4300.         {
  4301.             indx++ ;
  4302.             readin(argv[indx]) ;
  4303.             strcpy (filename,argv[indx]) ;
  4304.         }
  4305.         else
  4306.         {
  4307.             initialiseflags() ;
  4308.         }
  4309.     }
  4310.  
  4311.     
  4312.  
  4313.     action = noselection ;
  4314.  
  4315.     oktoexit=FALSE ;
  4316.     while (oktoexit!=TRUE)
  4317.     {
  4318.         getinput(&action, actbuffer) ;
  4319.  
  4320.         switch ( (int)action )
  4321.         {
  4322.  
  4323.             case noselection :
  4324.                 break ;
  4325.  
  4326.             case stoneplayed :
  4327.                 if (flag[PRACTICE]==off)
  4328.                 {
  4329.                     if (flag[STEPPING]==off)
  4330.                     {
  4331.                         legalmove = domove((COORD)actbuffer[0],(COORD)actbuffer[1],realboard) ;
  4332.                         if (legalmove==TRUE)
  4333.                             convertandstore((COORD)actbuffer[0],(COORD)actbuffer[1]) ;
  4334.                     }
  4335.                 }
  4336.                 else
  4337.                     (void)domove((COORD)actbuffer[0],(COORD)actbuffer[1],practiceboard) ;
  4338.                 break ;
  4339.  
  4340.             case undo :
  4341.  
  4342.                 if (flag[PRACTICE]==off)
  4343.                 {
  4344.                     if (flag[STEPPING]==on)
  4345.                         steppingindex = undorawindex ;
  4346.                     else
  4347.                     {
  4348.                         if (undorawindex < (rawindex-1))
  4349.                         {
  4350.                             displaystring("Comments also removed") ;
  4351.                             clearpromptline() ;
  4352.                         }
  4353.                         rawindex = undorawindex ;
  4354.                     }
  4355.  
  4356.                     removedifferences(realboard,
  4357.                               undoboard) ;
  4358.                     currentmove = savedcurrentmove ;
  4359.                     komove = savedkomove ;
  4360.                     blackcaptured = savedblackcaptured ;
  4361.                     whitecaptured = savedwhitecaptured ;
  4362.                     displaycaptured() ;
  4363.                     strcpy( lastmovestring, savedlastmovestring ) ;
  4364.                     displaylastmove(lastmovestring) ;
  4365.                     refreshmenu() ;
  4366.                 }
  4367.                 else
  4368.                 {
  4369.                     /* take flag off temporaily */
  4370.                     flag[PRACTICE] = off ;
  4371.                     removedifferences(practiceboard,
  4372.                               undopracticeboard) ;
  4373.                     flag[PRACTICE] = on ;
  4374.                     komove = savedkomove ;
  4375.                     nextpracticestone = savednextpracticestone ;
  4376.                 }
  4377.                 break ;
  4378.             case rawkeyboard :
  4379.                 if ( (flag[PRACTICE]==on) ||
  4380.                      ((flag[STEPPING]==off) &&
  4381.                       (flag[PRACTICE]==off)) )
  4382.                 {
  4383.                     legalmove = translateline(actbuffer, text, &skip) ;
  4384.                     if (legalmove==TRUE)
  4385.                     {
  4386.                         if (flag[PRACTICE]==off)
  4387.                             store(actbuffer) ;
  4388.                     }
  4389.                     else
  4390.                     {
  4391.                         clearpromptline() ;
  4392.                         displaystring(ILLEGAL) ;
  4393.                     }
  4394.                 }
  4395.                 clearpromptline() ;
  4396.                 break ;
  4397.             case lastmove :
  4398.                 toggleflag(LASTMOVE) ;
  4399.                 break ;
  4400.             case grid :
  4401.                 toggleflag(GRID) ;
  4402.                 break ;
  4403.             case numbers :
  4404.                 toggleflag(NUMBERS) ;
  4405.                 break ;
  4406.             case practice :
  4407.                 if (flag[PRACTICE]==off)
  4408.                 {
  4409.                     nextpracticestone=stonecolour(currentmove);
  4410.                     copyboard(realboard,practiceboard) ;
  4411.                     flag[PRACTICE] = on ;
  4412.                 }
  4413.                 else
  4414.                 {
  4415.                     flag[PRACTICE] = off ;
  4416.                     removedifferences(practiceboard,
  4417.                               realboard) ;
  4418.                 }
  4419.                 refreshmenu() ;
  4420.                 break ;
  4421.             case stepthrough :
  4422.                 startstepping() ;
  4423.                 break ;
  4424.             case readfrom :
  4425.                 if (flag[PRACTICE]==off)
  4426.                 {
  4427.                     tempfilename[0]=0 ;
  4428.                     getfilename(tempfilename) ;
  4429.                     if (tempfilename[0]!=0)
  4430.                     {
  4431.                         flag[STEPPING] = off ;
  4432.                         refreshmenu() ;
  4433.                         readin(tempfilename) ;
  4434.                         strcpy (filename,tempfilename) ;
  4435.                     }
  4436.                 }
  4437.                 break ;
  4438.             case pass :
  4439.                 passmove() ;
  4440.                 if (flag[PRACTICE]==off)
  4441.                     convertandstore(0,0) ;
  4442.                 break ;
  4443.             case writeto :
  4444.                 if ( (flag[PRACTICE]==off) &&
  4445.                      (flag[STEPPING]==off) )
  4446.                     writefileaway() ;
  4447.                 break ;
  4448.             case redraw :
  4449.                 erasescreen() ;
  4450.                 drawboard() ;
  4451.                 break ;
  4452.             case cd :
  4453.                 getdirectory(tempdirectory) ;
  4454.                 if (tempdirectory[0]!=0)
  4455.                 {
  4456.                     strcpy(directory,tempdirectory) ;
  4457.                 }
  4458.                 break ;
  4459.             case gotomove :
  4460.                 if ( (flag[STEPPING]==on) &&
  4461.                      (flag[PRACTICE]==off) )
  4462.                     gotoamove(actbuffer) ;
  4463.  
  4464.                 break ;
  4465.             case gotoline :
  4466.                 if ( (flag[STEPPING]==on) &&
  4467.                      (flag[PRACTICE]==off) )
  4468.                     gotoaline(actbuffer) ;
  4469.  
  4470.                 break ;
  4471.             case changesize :
  4472.                 if (flag[STEPPING]==on)
  4473.                 {
  4474.                     flag[STEPPING] = off ;
  4475.                     refreshmenu() ;
  4476.                 }
  4477.                 resetgame(actbuffer[0],0) ;
  4478.                 storenewgame(actbuffer[0],0) ;
  4479.                 break ;
  4480.             case changehandicap :
  4481.                 if (flag[STEPPING]==on)
  4482.                 {
  4483.                     flag[STEPPING] = off ;
  4484.                     refreshmenu() ;
  4485.                 }
  4486.                 resetgame(actbuffer[0],actbuffer[1]) ;
  4487.                 storenewgame(actbuffer[0],actbuffer[1]);
  4488.                 break ;
  4489.             case spacebar :
  4490.                 if (flag[PRACTICE]==on)
  4491.                 {
  4492.                     nextpracticestone=stonecolour(currentmove);
  4493.  
  4494.                     /* need to turn flag[PRACTICE] off
  4495.                      * temporarily so that the numbers
  4496.                      * will be printed in the stones
  4497.                      * that had been taken off in the
  4498.                      * practice
  4499.                      */
  4500.                     flag[PRACTICE] = off ;
  4501.                     removedifferences(practiceboard,
  4502.                               realboard) ;
  4503.                     flag[PRACTICE] = on ; 
  4504.  
  4505.                     copyboard ( realboard,practiceboard) ;
  4506.                 }
  4507.                 else
  4508.                 {
  4509.                     if (flag[STEPPING]==on)
  4510.                         readastep() ;
  4511.                 }
  4512.                 break ;
  4513.             case quit :
  4514.                 endterminalspecific() ;
  4515.                 oktoexit = TRUE ;
  4516.                 break ;
  4517.  
  4518.             default :
  4519.                 errorprint("Illegal action returned from getinput()");
  4520.                 break ;
  4521.         } /* switch */
  4522.  
  4523.     } /* while */
  4524.  
  4525.     exit(0);
  4526. }
  4527. SHAR_EOF
  4528. fi
  4529. if test -f 'go.curses.c'
  4530. then
  4531.     echo shar: "will not over-write existing file 'go.curses.c'"
  4532. else
  4533. cat << \SHAR_EOF > 'go.curses.c'
  4534. #include <curses.h>
  4535. #include <signal.h>
  4536. #include <string.h>
  4537. #include <sys/types.h>
  4538.  
  4539. #include "go.h"
  4540. #include "go.extern.h"
  4541.  
  4542. /* this is carriage return on the keyboard ^M, ('\n' is ^J) */
  4543. #define RETURN 13
  4544. #define BACKSPACE 0x08
  4545.  
  4546. #define CNTRL_C 0x03
  4547. #define CNTRL_D 0x04
  4548. #define CNTRL_G 0x07
  4549. #define CNTRL_H 0x08
  4550. #define CNTRL_L 0x0c
  4551. #define CNTRL_N 0x0e
  4552. #define CNTRL_P 0x10
  4553. #define CNTRL_R 0x12
  4554. #define CNTRL_T 0x14
  4555. #define CNTRL_U 0x15
  4556. #define CNTRL_W 0x17
  4557. #define CNTRL_X 0x18
  4558.  
  4559. #define EMPTYPOINT '.'
  4560. #define BLACKSTONE '@'
  4561. #define WHITESTONE 'O'
  4562. #define TICK '*'
  4563. #define NOTICK ' '
  4564.  
  4565. #define MENUSIZE 13    /* number of elements in the menu */
  4566.  
  4567. #define YLEDGE    1    /* Y coordinate (ie down), low edge of the board */
  4568. #define XLEDGE    3    /* X coordinate (ie across), low edge of the board */
  4569. #define XMENU    55    /* X coord, start of menu */
  4570. #define PROMPTLINE 23    /* Y coord, position where all text appears */
  4571.  
  4572. #define MENUSTR "  ^H - display Help menu"
  4573. #define ENTERSIZE "Enter size :"
  4574. #define ENTERHANDICAP "Enter handicap :"
  4575. #define ENTERGOTOMOVE "Enter a move or its number (eg D3 or 12) :"
  4576. #define ENTERGOTOLINE "Enter the line number :"
  4577. #define ENTERFILENAME "Enter filename :"
  4578. #define ENTERDIRECTORY "Enter directory :"
  4579. #define CAPTURES "Captures :"
  4580. #define CBLACK   "black = "
  4581. #define CWHITE   "white = "
  4582. #define LASTSTR "Last : "
  4583.  
  4584. /******************************************/
  4585. /* Global variables specific to this file */
  4586. /******************************************/
  4587.  
  4588. ONOFF menuflag ;
  4589.  
  4590. BOOLEAN menuofflasttime ;
  4591.  
  4592. char *menu[MENUSIZE] =
  4593. {
  4594.     "  ^P - Practice         ",    /* has to be as long as MENUSTR */
  4595.     "  ^T - step Through",
  4596.     "  ^R - Read from",
  4597.     "  ^U - Undo",
  4598.     "  ^C - Configure",
  4599.     "  ^W - Write to",
  4600.     "  ^L - redraw",
  4601.     "  ^D - change Directory",
  4602.     "  ^G - Goto move (   )",
  4603.     "  ^N - goto liNe (   )",
  4604.     "  ^X - eXit",
  4605.     "",
  4606.     "  ^H - clear Help menu",
  4607. } ;
  4608.  
  4609. int xmiddle ;        /* Position to write the 'stones captured' info */
  4610. BOOLEAN killline ;    /* Inicates that abort/del has been pressed */
  4611.  
  4612. void displayflag() ;
  4613.  
  4614.  
  4615. /*
  4616.  * Function:    clearpromptline
  4617.  *        
  4618.  * Description:     Clears the player input/comment display line.
  4619.  *        
  4620.  *        
  4621.  *        
  4622.  * Globals affected:    none
  4623.  *            
  4624.  */
  4625. void
  4626. clearpromptline()
  4627. {
  4628.     scroll(stdscr) ;
  4629.     refresh() ;
  4630. }
  4631.  
  4632. /*
  4633.  * Function:    displaystring()
  4634.  *        
  4635.  * Description:    Displays a string in the promptline, if it ends in a 
  4636.  *        newline this is removed before output.
  4637.  *        
  4638.  *        
  4639.  * Globals affected:    none
  4640.  *            
  4641.  */
  4642. void
  4643. displaystring(s)
  4644. char *s ;
  4645. {
  4646. char len ;
  4647.  
  4648.     len = strlen(s) ;
  4649.  
  4650.     if ( *(s+len-1) == '\n' )
  4651.     {
  4652.         *(s+len-1) = '\0' ;
  4653.         mvaddstr(PROMPTLINE,0,s) ;
  4654.         *(s+len-1) = '\n' ;
  4655.     }
  4656.     else
  4657.     {
  4658.         mvaddstr(PROMPTLINE,0,s) ;
  4659.     }
  4660.     refresh() ;
  4661. }
  4662.  
  4663. /*
  4664.  * Function:    errorprint()
  4665.  *        
  4666.  * Description:    Prints a string in error format
  4667.  *        
  4668.  *        
  4669.  *        
  4670.  * Globals affected:    none
  4671.  *            
  4672.  */
  4673. void
  4674. errorprint(s)
  4675. char *s ;
  4676. {
  4677.     standout() ;
  4678.     displaystring(s) ;
  4679.     standend() ;
  4680.     clearpromptline() ;
  4681.     displaystring(" ... hit any key to continue") ;
  4682.     clearpromptline() ;
  4683.     displaystring("(if the program crashes type  '^Jstty sane^J')" ) ;
  4684.     getch() ;
  4685. }
  4686.  
  4687. /*
  4688.  * Function:    displaylastmove
  4689.  *        
  4690.  * Description:    Checks the state of teh last move falg then if required
  4691.  *        displays the last move.
  4692.  *        
  4693.  *        
  4694.  * Globals affected:    none
  4695.  *            
  4696.  */
  4697. void
  4698. displaylastmove(str)
  4699. char str[] ;
  4700. {
  4701. char i ;
  4702.  
  4703.     if (flag[LASTMOVE]==on)
  4704.     {
  4705.         mvaddstr(YLEDGE+4,xmiddle,LASTSTR) ;
  4706.         mvaddstr(YLEDGE+4,xmiddle+strlen(LASTSTR),str) ;
  4707.         for (i=strlen(str);i<4;i++)
  4708.         {
  4709.             mvaddch(YLEDGE+4,xmiddle+strlen(LASTSTR)+i,' ') ;
  4710.         }
  4711.     }
  4712. }
  4713.  
  4714. /*
  4715.  * Function:    erasescreen()
  4716.  *        
  4717.  * Description:    Clear the whole screen
  4718.  *        
  4719.  *        
  4720.  *        
  4721.  * Globals affected:    none
  4722.  *            
  4723.  */
  4724. void
  4725. erasescreen()
  4726. {
  4727.     clear() ;
  4728.     refresh() ;
  4729.  
  4730.     menuofflasttime = FALSE ;
  4731.     displaymenu() ;
  4732.     refresh() ;
  4733.  
  4734. }
  4735.  
  4736. /*
  4737.  * Function:    reconfigure()
  4738.  *        
  4739.  * Description:    Terminal specific code after a configure of the board
  4740.  *        
  4741.  *        
  4742.  *        
  4743.  * Globals affected:    none
  4744.  *            
  4745.  */
  4746. void
  4747. reconfigure()
  4748. {
  4749.     if (size>MENUSIZE)
  4750.         setscrreg(size+2,23) ;
  4751.     else
  4752.         setscrreg(MENUSIZE+2,23) ;
  4753.  
  4754.     /* put the captured score between the board and the menu */
  4755.     xmiddle = ( ( (size-1)*2+XLEDGE ) + XMENU ) / 2 - ( strlen(CAPTURES)/2 ) ;
  4756.  
  4757. }
  4758.  
  4759. /*
  4760.  * Function:    getinput()
  4761.  *        
  4762.  * Description:    Gets input from keyboard.
  4763.  *        Sets action to be one of the following, with corresponding
  4764.  *        data in the buffer.
  4765.  *        Any strings returned in the buffer always end with a newline
  4766.  *        and a null.
  4767.  *
  4768.  *        action        actbuffer
  4769.  *        ------        ---------
  4770.  *        cd        null
  4771.  *        gotomove    decimal string "1" to "999" or a move eg "D3",
  4772.  *                ending with newline. Maximum of four bytes long,
  4773.  *                plus '\0'.
  4774.  *        gotoline    decimal string "1" to "999" ending with newline.
  4775.  *                Maximum of four bytes long, plus '\0'.
  4776.  *        changehandicap    first byte is size, second is handicap
  4777.  *        numbers        null    (NOT AVAILABLE WITH CURSES)
  4778.  *        pass        null    (NOT AVAILABLE WITH CURSES)
  4779.  *        practice    null
  4780.  *        quit        null
  4781.  *        rawkeyboard    string typed in from the keyboard + "\n"
  4782.  *        readfrom    null
  4783.  *        redraw        null
  4784.  *        changesize    first byte indicates new size
  4785.  *                (NOT AVAILABLE WITH CURSES)
  4786.  *        spacebar    null
  4787.  *        stoneplayed    x and y in the first two bytes
  4788.  *                (NOT AVAILABLE WITH CURSES)
  4789.  *        stepthrough    null
  4790.  *        undo        null
  4791.  *        writeto        null
  4792.  *        
  4793.  *        This function handles the displaying of the menu (together
  4794.  *        with the associated flags). The current move must be
  4795.  *        displayed on the menu in a relevant place.
  4796.  *        
  4797.  * Globals affected:    none
  4798.  *            
  4799.  */
  4800. void
  4801. getinput ( action, actbuffer ) 
  4802. ACTIONTYPE *action ;
  4803. char       actbuffer[MAXLINELENGTH] ;
  4804. {
  4805.  
  4806. chtype key ;
  4807. char sizestr[4] ;
  4808. char handstr[3] ;
  4809.  
  4810.     /* move the cursor to the menu to indicate ready for input */
  4811.     if (menuflag==on)
  4812.         move(YLEDGE+MENUSIZE-1,XMENU+strlen(menu[MENUSIZE-1])) ;
  4813.     else
  4814.         move(YLEDGE,XMENU+strlen(MENUSTR)) ;
  4815.  
  4816.     refresh() ;
  4817.  
  4818.     key = getch() ;
  4819.  
  4820.     switch(key)
  4821.     {
  4822.         case CNTRL_C :    
  4823.                 mvaddstr(PROMPTLINE,0,ENTERSIZE) ;
  4824.                 refresh() ;
  4825.                 collectstring(strlen(ENTERSIZE),
  4826.                           sizestr,
  4827.                           0,2 ) ;
  4828.                 clearpromptline() ;
  4829.                 actbuffer[0] = atoi(sizestr) ;
  4830.  
  4831.                 mvaddstr(PROMPTLINE,0,ENTERHANDICAP) ;
  4832.                 refresh() ;
  4833.                 collectstring(strlen(ENTERHANDICAP),
  4834.                           handstr,
  4835.                           0,1 ) ;
  4836.                 clearpromptline() ;
  4837.                 actbuffer[1] = atoi(handstr) ;
  4838.  
  4839.                 *action = changehandicap ;
  4840.                 break;
  4841.         case CNTRL_D :    
  4842.                 *action = cd ;
  4843.                 break;
  4844.         case CNTRL_G :    
  4845.                 clearpromptline() ;
  4846.                 mvaddstr(PROMPTLINE,0,ENTERGOTOMOVE) ;
  4847.                 refresh() ;
  4848.                 collectstring(strlen(ENTERGOTOMOVE),
  4849.                           actbuffer,
  4850.                           0,3 ) ;
  4851.                 strcat(actbuffer,"\n") ;
  4852.                 clearpromptline() ;
  4853.                 *action = gotomove ;
  4854.                 break;
  4855.         case CNTRL_L :    
  4856.                 *action = redraw ;
  4857.                 break;
  4858.  
  4859.         case CNTRL_N :    
  4860.                 clearpromptline() ;
  4861.                 mvaddstr(PROMPTLINE,0,ENTERGOTOLINE) ;
  4862.                 refresh() ;
  4863.                 collectstring(strlen(ENTERGOTOLINE),
  4864.                           actbuffer,
  4865.                           0,3 ) ;
  4866.                 strcat(actbuffer,"\n") ;
  4867.                 clearpromptline() ;
  4868.                 *action = gotoline ;
  4869.                 break;
  4870.  
  4871.         case CNTRL_H :    if (menuflag==on)
  4872.                     menuflag=off ;
  4873.                 else
  4874.                     menuflag=on ;
  4875.  
  4876.                 displaymenu() ;
  4877.                 *action = noselection ;
  4878.                 break ;
  4879.  
  4880.         case CNTRL_P :    
  4881.                 clearpromptline() ;
  4882.                 *action = practice ;
  4883.                 break;
  4884.         case CNTRL_R :    
  4885.                 *action = readfrom ;
  4886.                 break;
  4887.         case CNTRL_T :    
  4888.                 *action = stepthrough ;
  4889.                 break;
  4890.         case CNTRL_U :
  4891.                 *action = undo ;
  4892.                 break ;
  4893.         case CNTRL_W :    
  4894.                 *action = writeto ;
  4895.                 break;
  4896.  
  4897.         case CNTRL_X :    *action = quit ;
  4898.                 break ;
  4899.  
  4900.  
  4901.         case ' ' :    *action = spacebar ;
  4902.                 break ;
  4903.  
  4904.         default :    mvaddch(PROMPTLINE,0,(char)key) ;
  4905.                 refresh() ;
  4906.                 actbuffer[0]=(char)key ;
  4907.                 collectstring(0,actbuffer,1,MAXCHARS) ;
  4908.                 strcat(actbuffer,"\n") ;
  4909.                 *action= rawkeyboard ;
  4910.                 break ;
  4911.     }
  4912. }
  4913.  
  4914. /*
  4915.  * Function:    drawgrid
  4916.  *        
  4917.  * Description:    Draws the 'A' to 'T' along the top and 19 to 1 down the side
  4918.  *        Providing that the grid flag is set.
  4919.  *        
  4920.  *        
  4921.  * Globals affected:    none
  4922.  *            
  4923.  */
  4924. void
  4925. drawgrid()
  4926. {
  4927. char str[3] ;
  4928. int indx ;
  4929.  
  4930.     if (flag[GRID]==on)
  4931.     {
  4932.         for (indx=1;indx<=size;indx++)
  4933.         {
  4934.             if (indx<=8)
  4935.             {
  4936.                 mvaddch(0,(indx-1)*2+XLEDGE,'A'+indx-1) ;
  4937.             }
  4938.             else
  4939.             {
  4940.             mvaddch(0,(indx-1)*2+XLEDGE,'J'+indx-9) ;
  4941.             }
  4942.     
  4943.             str[0] = 0 ;
  4944.             sprintf(str,"%d",size+1-indx) ;
  4945.             mvaddstr(YLEDGE+indx-1,0,str) ;
  4946.     
  4947.             refresh() ;
  4948.         }
  4949.     }
  4950. }
  4951.  
  4952. /*
  4953.  * Function:    drawempty
  4954.  *        
  4955.  * Description:    Draws an empty place on the board
  4956.  *        
  4957.  *        
  4958.  *        
  4959.  * Globals affected:    none
  4960.  *            
  4961.  */
  4962. void
  4963. drawempty(x,y)
  4964. COORD x,y ;
  4965. {
  4966.     mvaddch( YLEDGE+y-1, (x-1)*2+XLEDGE, EMPTYPOINT ) ;
  4967.     refresh() ;
  4968. }
  4969.  
  4970. /*
  4971.  * Function:    drawstone
  4972.  *        
  4973.  * Description:    Draws a stone, with number if possible/allowed
  4974.  *        
  4975.  *        
  4976.  *        
  4977.  * Globals affected:    none
  4978.  *            
  4979.  */
  4980. void
  4981. drawstone(x,y,n,c)
  4982. COORD x,y ;
  4983. MOVENUMBER n ;
  4984. COLOUR c ;
  4985. {
  4986.     if (flag[PRACTICE]==on)
  4987.         attron(A_BOLD) ;
  4988.         /*standout() ; - reverse video */
  4989.         
  4990.     if (c==black)
  4991.         mvaddch( YLEDGE+y-1, (x-1)*2+XLEDGE, BLACKSTONE ) ;
  4992.     else
  4993.         mvaddch( YLEDGE+y-1, (x-1)*2+XLEDGE, WHITESTONE ) ;
  4994.  
  4995.     if (flag[PRACTICE]==on)
  4996.         attroff(A_BOLD) ;
  4997.         /*standend() ; - reverse video */
  4998.  
  4999.     refresh() ;
  5000.  
  5001.     displaymenu() ;
  5002. }
  5003.  
  5004. /*
  5005.  * Function:    getdirectory
  5006.  *        
  5007.  * Description:    If directory is already set then copy directory into dn.
  5008.  *        Display dn, and allow editting of it with backspace and
  5009.  *        kill.
  5010.  *        
  5011.  * Globals affected:    none
  5012.  *            
  5013.  */
  5014. void
  5015. getdirectory(dn)
  5016. char dn[] ;
  5017. {
  5018.     clearpromptline() ;
  5019.  
  5020.     mvaddstr(PROMPTLINE,0,ENTERDIRECTORY) ;
  5021.  
  5022.     dn[0]=0 ;
  5023.     strcpy(dn,directory) ;
  5024.     mvaddstr(PROMPTLINE,strlen(ENTERDIRECTORY),dn) ;
  5025.  
  5026.     refresh() ;
  5027.  
  5028.     collectstring(strlen(ENTERDIRECTORY),
  5029.               dn,
  5030.               strlen(dn),
  5031.               MAXCHARS ) ;
  5032.  
  5033.     clearpromptline() ;
  5034. }
  5035.  
  5036. /*
  5037.  * Function:    getfilename
  5038.  *        
  5039.  * Description:    If filename is already set then copy filename into fn.
  5040.  *        Display fn, and allow editting of it with backspace and
  5041.  *        kill.
  5042.  *        
  5043.  * Globals affected:    none
  5044.  *            
  5045.  */
  5046. void
  5047. getfilename(fn)
  5048. char fn[] ;
  5049. {
  5050.     clearpromptline() ;
  5051.  
  5052.     mvaddstr(PROMPTLINE,0,ENTERFILENAME) ;
  5053.  
  5054.     fn[0]=0 ;
  5055.     strcpy(fn,filename) ;
  5056.     mvaddstr(PROMPTLINE,strlen(ENTERFILENAME),fn) ;
  5057.  
  5058.     refresh() ;
  5059.  
  5060.     collectstring(strlen(ENTERFILENAME),
  5061.               fn,
  5062.               strlen(fn),
  5063.               MAXLINELENGTH ) ;
  5064.  
  5065.     clearpromptline() ;
  5066. }
  5067.  
  5068. /*
  5069.  * Function:    displaycaptured
  5070.  *        
  5071.  * Description:    Displays on the screen how many of each colour have been taken.
  5072.  *        
  5073.  * Globals affected:    none
  5074.  *            
  5075.  */
  5076. void
  5077. displaycaptured()
  5078. {
  5079. char taken[4] ;
  5080.  
  5081.     mvaddstr(YLEDGE,xmiddle,CAPTURES) ;
  5082.     mvaddstr(YLEDGE+1,xmiddle,CBLACK) ;
  5083.     mvaddstr(YLEDGE+2,xmiddle,CWHITE) ;
  5084.  
  5085.     taken[0] = 0 ;
  5086.     sprintf(taken,"%d",blackcaptured) ;
  5087.     mvaddstr(YLEDGE+1,xmiddle+strlen(CBLACK),taken) ;
  5088.  
  5089.     taken[0] = 0 ;
  5090.     sprintf(taken,"%d",whitecaptured) ;
  5091.     mvaddstr(YLEDGE+2,xmiddle+strlen(CWHITE),taken) ;
  5092. }
  5093.  
  5094. /*
  5095.  * Function:    refreshmenu()
  5096.  *        
  5097.  * Description:    This function is called when some information on the menu
  5098.  *        has changed, the screen needs updating.
  5099.  *        
  5100.  *        
  5101.  * Globals affected:    none
  5102.  *            
  5103.  */
  5104. void
  5105. refreshmenu()
  5106. {
  5107.     displayflag(STEPPING) ;
  5108.     displayflag(PRACTICE) ;
  5109.  
  5110.     /* other flags are ignored in curses version */
  5111.  
  5112.     displaymenu() ;
  5113. }
  5114.  
  5115. /*
  5116.  * Function:    startterminalspecific
  5117.  *        
  5118.  * Description:    Graphics routines initialisation etc.
  5119.  *        
  5120.  *        
  5121.  *        
  5122.  * Globals affected:    none
  5123.  *            
  5124.  */
  5125. void
  5126. startterminalspecific(argc,argv)
  5127. int argc ;
  5128. char *argv[] ;
  5129. {
  5130. int handler() ;
  5131.  
  5132.       signal(SIGINT, handler) ;    /*  handle abort (del)    */
  5133.  
  5134.     initscr() ;
  5135.     nonl() ;
  5136.     cbreak() ;
  5137.     noecho() ;
  5138.     scrollok(stdscr,1) ;
  5139.  
  5140.  
  5141.     menuflag = off ;
  5142.  
  5143.     menuofflasttime = FALSE ;
  5144.  
  5145.     displaystring(version) ;
  5146.     setscrreg(21,23) ;
  5147.  
  5148. }
  5149.  
  5150. /*
  5151.  * Function:    endterminalspecific
  5152.  *        
  5153.  * Description:    Graphics routines termination before exit.
  5154.  *        
  5155.  *        
  5156.  *        
  5157.  * Globals affected:    none
  5158.  *            
  5159.  */
  5160. void
  5161. endterminalspecific()
  5162. {
  5163.     clearpromptline() ;
  5164.     endwin() ;
  5165. }
  5166.  
  5167. /******************************/
  5168. /* End of Interface functions */
  5169. /******************************/
  5170.  
  5171.  
  5172. /*
  5173.  * Function:    displayflag
  5174.  *        
  5175.  * Description:    Displays on the menu the status of the specified flag.
  5176.  *        
  5177.  * Globals affected:    none
  5178.  *            
  5179.  */
  5180. void
  5181. displayflag(f)
  5182. char f ;
  5183. {
  5184. char action ;
  5185.  
  5186.     if (flag[f]==off)
  5187.         action = NOTICK ;
  5188.     else
  5189.         action = TICK ;
  5190.  
  5191.     switch(f)
  5192.     {
  5193.         case STEPPING :    menu[1][0] = action ;
  5194.                 break ;
  5195.         case PRACTICE : menu[0][0] = action ;
  5196.                 break ;
  5197.         case NUMBERS :
  5198.         case GRID :
  5199.         case LASTMOVE :
  5200.                 /* ignore, these are not displayed in curses */
  5201.                 break ;
  5202.             
  5203.         default :    errorprint("default case in displayflag()") ;
  5204.                 break ;
  5205.         
  5206.     }
  5207.  
  5208. }
  5209. /*
  5210.  * Function:    removemenuitem()
  5211.  *        
  5212.  * Description:    Clears item n of the menu off the screen
  5213.  *        
  5214.  *        
  5215.  *        
  5216.  * Globals affected:    none
  5217.  *            
  5218.  */
  5219. removemenuitem(n)
  5220. int n ;
  5221. {
  5222. int count ;
  5223.  
  5224.     for ( count=0 ; count<strlen(menu[n]) ; count++ )
  5225.     {
  5226.         mvaddch(YLEDGE+n,XMENU+count,' ') ;
  5227.     }
  5228.     refresh() ;
  5229. }
  5230.  
  5231. /*
  5232.  * Function:    displaymenu()
  5233.  *        
  5234.  * Description:    Displays the menu according to the menuflag
  5235.  *        
  5236.  *        
  5237.  * Globals affected:    menuofflasttime
  5238.  *            
  5239.  */
  5240. displaymenu()
  5241. {
  5242. int indx ;
  5243. char gotostr[4] ;
  5244.  
  5245.         if (menuflag==off)
  5246.         {
  5247.             if (menuofflasttime == FALSE)
  5248.             {
  5249.                 for (indx=(MENUSIZE-1);indx>=0;indx--)
  5250.                 {
  5251.                     removemenuitem(indx) ;
  5252.                 }
  5253.                 mvaddstr(YLEDGE,XMENU,MENUSTR) ;
  5254.                 menuofflasttime = TRUE ;
  5255.                 refresh() ;
  5256.             }
  5257.         }
  5258.         else
  5259.         {
  5260.             for (indx=0;indx<MENUSIZE;indx++)
  5261.             {
  5262.                 mvaddstr(YLEDGE+indx,XMENU,menu[indx]) ;
  5263.             }
  5264.             menuofflasttime = FALSE ;
  5265.  
  5266.             gotostr[0] = 0 ;
  5267.             sprintf(gotostr,"%d",currentmove-1) ;
  5268.             mvaddstr(YLEDGE+8,XMENU+18,gotostr) ;
  5269.  
  5270.             gotostr[0] = 0 ;
  5271.             sprintf(gotostr,"%d",steppingindex) ;
  5272.             mvaddstr(YLEDGE+9,XMENU+18,gotostr) ;
  5273.  
  5274.             refresh() ;
  5275.         }
  5276.  
  5277.  
  5278.  
  5279. }
  5280.  
  5281. /*
  5282.  * Function:    collectstring()
  5283.  *        
  5284.  * Description:    Allows player to enter a sting of chars on the promptline,
  5285.  *        if strsize is non-zero this implies  some characters are
  5286.  *        already persent. The string can be editted using backspace
  5287.  *        or terminal interrupt key (removes the whole line).
  5288.  *        
  5289.  *        
  5290.  * Globals affected:    none
  5291.  *            
  5292.  */
  5293. collectstring(xstart,str,strsize,max)
  5294. int xstart ;    /* position on PROMPTLINE where initial string started */
  5295. char *str ;    /* string to be filled */
  5296. int strsize ;    /* count of chars already in str */
  5297. int max ;    /* maximum numbers characters that can be input */
  5298. {
  5299.  
  5300. #define NO_CHAR (chtype)(-1)    /* no key pressed yet */
  5301.  
  5302. chtype key ;
  5303. int indx ;
  5304.  
  5305.     key = NO_CHAR ;
  5306.  
  5307.     nodelay(stdscr,1) ;
  5308.  
  5309.     killline = FALSE ;    /* see handler() */
  5310.  
  5311.     while ( key!=RETURN )
  5312.     {
  5313.         key = getch() ;
  5314.  
  5315.         if (killline==TRUE)
  5316.         {
  5317.             if (strsize>0)
  5318.             {
  5319.                 for (indx=xstart+strsize-1;
  5320.                      indx>=xstart;
  5321.                      indx--)
  5322.                     mvaddch(PROMPTLINE,indx,' ');
  5323.                 strsize = 0 ;
  5324.                 move(PROMPTLINE,xstart) ;
  5325.                 refresh() ;
  5326.             }
  5327.             killline = FALSE ;
  5328.         }
  5329.  
  5330.         if (key!=NO_CHAR)
  5331.         {
  5332.             switch(key)
  5333.             {
  5334.                 case RETURN :    *(str+strsize) = 0 ;
  5335.                         break ;
  5336.     
  5337.                 case BACKSPACE :if (strsize>0)
  5338.                         {
  5339.                             strsize-- ;
  5340.                             mvaddch(PROMPTLINE,
  5341.                                 xstart+strsize,
  5342.                                 ' ') ;
  5343.                             move(PROMPTLINE,xstart+strsize);
  5344.                             refresh() ;
  5345.                         }
  5346.                         break ;
  5347.     
  5348.                 default :    if (strsize<max)
  5349.                         {
  5350.                             *(str+strsize) = (char)key ;
  5351.                             mvaddch(PROMPTLINE,xstart+strsize,(char)key) ;
  5352.                             refresh() ;
  5353.                             strsize++ ;
  5354.                         }
  5355.                         break ;
  5356.             } /* end switch */
  5357.  
  5358.         } /* end if ! NO_CHAR */
  5359.  
  5360.     } /* end while */
  5361.  
  5362.     nodelay(stdscr,0) ;
  5363. }
  5364.  
  5365. /*
  5366.  * Function:    handler
  5367.  *        
  5368.  * Description:    Deals with interrupts sent to this process, the only one
  5369.  *        we are interested in is 'terminal interrupt'
  5370.  *        
  5371.  *        
  5372.  * Globals affected:    killline
  5373.  *            
  5374.  */
  5375. handler(a)
  5376. int a ;
  5377. {
  5378.     /* reset the signal so it can be caught again */
  5379.       signal(SIGINT, handler) ;    /*  handle abort (del)    */
  5380.  
  5381.     switch (a)
  5382.     {
  5383.         case SIGINT :    killline = TRUE ;
  5384.                 break ;
  5385.  
  5386.         default :    beep() ;
  5387.                 break ;
  5388.     }
  5389.     return(0) ;
  5390. }
  5391.  
  5392. SHAR_EOF
  5393. fi
  5394. if test -f 'go.extern.h'
  5395. then
  5396.     echo shar: "will not over-write existing file 'go.extern.h'"
  5397. else
  5398. cat << \SHAR_EOF > 'go.extern.h'
  5399. /*
  5400.  * This is used as an include file for the terminal interface driver routines,
  5401.  * it contains all the external global varibales defined in go.c and any
  5402.  * functions found in go.c that could be useful to the driver.
  5403.  */
  5404.  
  5405. extern char version[] ;
  5406. extern COLOUR black ;
  5407. extern COLOUR white ;
  5408.  
  5409. extern char size ;
  5410. extern char handicap ;
  5411.  
  5412. extern MOVENUMBER currentmove ;
  5413. extern int steppingindex ;
  5414.  
  5415. extern char filename[FILENAMELEN] ;
  5416. extern char directory[MAXLINELENGTH] ;
  5417.  
  5418. extern ONOFF flag[5] ;
  5419.  
  5420. extern int blackcaptured ;
  5421. extern int whitecaptured ;
  5422.  
  5423.  
  5424. BOOLEAN starpoint() ;
  5425. POSTYPE postype() ;
  5426. SHAR_EOF
  5427. fi
  5428. if test -f 'go.h'
  5429. then
  5430.     echo shar: "will not over-write existing file 'go.h'"
  5431. else
  5432. cat << \SHAR_EOF > 'go.h'
  5433. /*
  5434.  * #defines and types useful to both go.c and go.<driver>.c
  5435.  */
  5436.  
  5437. #define EMPTY 0
  5438.  
  5439. /* max board array size [0] is always empty */
  5440. #define MAX 20 
  5441.  
  5442. #define MOVENUMBER unsigned short /* 1 to 999 */
  5443. #define COORD      unsigned short /* 1 to 19 */
  5444. #define COLOUR     unsigned short /* If handicap is zero then 1 = black and
  5445.                    * 2 = white, else 1 = white and 2 = black
  5446.                    */
  5447.  
  5448. /* flag definitions */
  5449. #define STEPPING 0
  5450. #define PRACTICE 1
  5451. #define NUMBERS  2
  5452. #define GRID     3
  5453. #define LASTMOVE 4
  5454.  
  5455. /* largest line length in the file */
  5456. #define MAXLINELENGTH 82
  5457. #define MAXCHARS (MAXLINELENGTH-2) /* allow room for "\n\0" */
  5458.  
  5459. /* longest filename length */
  5460. #define FILENAMELEN 14
  5461.  
  5462. typedef enum POSTYPE
  5463. {
  5464.      topleft,
  5465.      topside,
  5466.      topright,
  5467.      leftside,
  5468.      middle,
  5469.      rightside,
  5470.      bottomleft,
  5471.      bottomside,
  5472.      bottomright
  5473. } POSTYPE ;
  5474.  
  5475.  
  5476.  
  5477.  
  5478. typedef enum ACTIONTYPE
  5479. {
  5480.     noselection,
  5481.     quit,
  5482.     stoneplayed,
  5483.     rawkeyboard,
  5484.     lastmove,
  5485.     numbers,
  5486.     grid,
  5487.     practice,
  5488.     stepthrough,
  5489.     changesize,
  5490.     readfrom,
  5491.     pass,
  5492.     undo,
  5493.     writeto,
  5494.     redraw,
  5495.     cd,
  5496.     gotomove,
  5497.     gotoline,
  5498.     changehandicap,
  5499.     spacebar
  5500. } ACTIONTYPE ;
  5501.  
  5502.  
  5503. typedef enum ONOFF { on,off } ONOFF ;
  5504.  
  5505.  
  5506. #ifndef TRUE    /* curses.h already declares its own TRUE and FALSE */
  5507.  
  5508. typedef enum BOOLEAN
  5509. {
  5510.     FALSE = 0,
  5511.     TRUE = 1
  5512. } BOOLEAN ;
  5513.  
  5514. #else
  5515.  
  5516. #define BOOLEAN unsigned char
  5517.  
  5518. #endif
  5519.  
  5520. typedef struct XY
  5521. {
  5522.     unsigned char x ;
  5523.     unsigned char y ;
  5524. } XY ;
  5525.  
  5526.  
  5527. SHAR_EOF
  5528. fi
  5529. if test -f 'go.interface.h'
  5530. then
  5531.     echo shar: "will not over-write existing file 'go.interface.h'"
  5532. else
  5533. cat << \SHAR_EOF > 'go.interface.h'
  5534. /*
  5535.  * Definitions of all the functions that need to be supplied by the terminal 
  5536.  * interface driver
  5537.  */
  5538. extern void clearpromptline() ;
  5539. extern void displaycaptured() ;
  5540. extern void displaylastmove() ;
  5541. extern void displaystring() ;
  5542. extern void drawempty() ;
  5543. extern void drawgrid() ;
  5544. extern void drawstone() ;
  5545. extern void endterminalspecific() ;
  5546. extern void erasescreen() ;
  5547. extern void errorprint() ;
  5548. extern void getdirectory() ;
  5549. extern void getfilename() ;
  5550. extern void getinput() ;
  5551. extern void reconfigure() ;
  5552. extern void refreshmenu() ;
  5553. extern void startterminalspecific() ;
  5554. SHAR_EOF
  5555. fi
  5556. if test -f 'go.mmx'
  5557. then
  5558.     echo shar: "will not over-write existing file 'go.mmx'"
  5559. else
  5560. cat << \SHAR_EOF > 'go.mmx'
  5561. .DS C
  5562.  
  5563.  
  5564.  
  5565.  
  5566.  
  5567.  
  5568. .B
  5569. GO MANUAL
  5570.  
  5571. .I
  5572. User Guide and Programmer Reference
  5573. .R
  5574.  
  5575.  
  5576.  
  5577.  
  5578.  
  5579.  
  5580.  
  5581.  
  5582.  
  5583.  
  5584.  
  5585.  
  5586.  
  5587.  
  5588.  
  5589. .DE
  5590. .DS CB
  5591. GO - is a game that  originated in China over
  5592. 4000 years ago  and is now the  national game
  5593. of Japan. It's rules  are simple but the game
  5594. can take a life time to master.  An advantage
  5595. of the  game is that  there is a handicapping
  5596. system whereby less experienced players still
  5597. give stronger players a good match.
  5598. .DE
  5599. .SK
  5600. .H 1 "INTRODUCTION"
  5601. .P
  5602. This document describes a program that provides a screen based board for the
  5603. playing of the game Go. It is written in C for the Unix operating system and
  5604. the code is split in such a way as to enable the program to run on any type of
  5605. terminal, providing the terminal interface driver has been written. At the
  5606. moment there are drivers for standard terminals that can cope with the Unix
  5607. "curses" package and for the 630 DMD terminal. This document makes references
  5608. to both these interfaces.
  5609. .P
  5610. Section 2 gives a brief walk through of how to get going using the program.
  5611. Section 3 gives a beginners tutorial on the rules of Go, section 4 describes
  5612. all the features of the program and how to use them.
  5613. .H 1 "GETTING STARTED"
  5614. .H 2 "Sample .profile"
  5615. .P
  5616. Initially a player should edit their .profile to include the following lines :-
  5617. .DS
  5618.     .
  5619.     .
  5620.     GO=/d1/usr/go            #or where-ever the root is
  5621.     export GO
  5622.     PATH=$PATH:$GO/bin
  5623.     alias go="go -d $GO/games"    #Set default directory
  5624.     .
  5625.     .
  5626. .DE
  5627. .P
  5628. The $GO environment variable should point to the root of the go directory tree.
  5629. $GO/games contains some sample games as well as the 'tutoring' games mentioned
  5630. in the sections below. Later the alias to set the default directory could point
  5631. to the player's personal games directory. (see section:INVOCATION)
  5632. .H 2 "For Standard Terminals"
  5633. .P
  5634. Typing "go" at the Unix prompt the screen will be cleared, to display the menu
  5635. of options type cntrl-H ( a further cntrl-H will remove the menu, it is not
  5636. necessary to display the menu to access the commands, it is just a "reminder" ).
  5637. Type cntrl-T ( for "step Through" ) and you will be prompted for a filename,
  5638. enter 'start.go' and press return the program will then be reading in this file.
  5639. Start.go is a file that will guide you through the basics of using the program.
  5640. .H 2 "For 630 Terminals"
  5641. .P
  5642. Draw a fairly large window and type "go" at the Unix prompt, the window
  5643. will then begin to fill. After the screen has filled, the window will change
  5644. shape to become square and
  5645. program is ready. Button 3 of the mouse presents you with a menu of options,
  5646. select "step through" and enter the filename start.630.go which will guide you
  5647. through using the basics of the program. Note that as well as being able to
  5648. enter moves as described you can also play them with button 1 of the mouse.
  5649. Button 2 can also be used as a substitute for the space bar.
  5650. .P
  5651. Moves will have the number displayed on the stone if the number flag is set,
  5652. see below. Numbers are not displayed on practice stones or handicap stones.
  5653. .P
  5654. Two people can play face to face using the 630 version of the program : one
  5655. player takes the mouse, the other the keyboard.
  5656. .H 1 "GO FOR BEGINNERS"
  5657. .P
  5658. Once you have mastered using the program, section 2 above, step through a
  5659. file called 'basics.go' which explains the rules of the game. 
  5660. .H 2 "Handicapping and Ranking System"
  5661. Players of Go are rated using a 'kyu' (pronounced "Q") ranking system,
  5662. beginners generally start at around 25 kyu, more accomplished players
  5663. have a lower kyu rating. The difference in kyu between two players is the
  5664. number of handicap stones that are to be placed on the board in set positions
  5665. before the game starts.
  5666. .P
  5667. For example if a 17 kyu plays against a  21 kyu then the less experienced
  5668. player (the 21 kyu) has four of his/her stones placed at the 4,4 points in
  5669. each corner of a 19x19 board (such handicap points are sometimes called "star
  5670. points"). Notice that the less experienced player
  5671. always plays black and that after the handicap stones are placed then it is
  5672. white's first move.
  5673. .P
  5674. After a player improves beyond 1 kyu then he/she progresses up in 'dan' grades
  5675. ie the sequence goes ... 2 kyu, 1 kyu, 1 dan (or sho-dan), 2 dan, 3 dan, etc up
  5676. to 9 dan.
  5677. The best players in Europe are around 4-5 dan and in Japan a 6 dan or higher 
  5678. could earn a living as a professional go player !
  5679. .H 1 "THE DETAILS"
  5680. .H 2 "Modes of Use"
  5681. .P
  5682. There a two basic ways to use the program:-
  5683. .H 3 "Learning/Researching"
  5684. Step through a file, using the space bar. Allow the player to select practice
  5685. and try some moves out, while practicing the spacebar removes the practice
  5686. stones, select "practice" again to continue to step. Writing of files away is
  5687. prevented when stepping. Should the player wish to quit and return at a later
  5688. date back to the place where he/she left off, then before quitting look at the
  5689. menu for "goto line" it will indicate the current line in the file.
  5690. .P
  5691. It is also possible to goto any move within a game by specifying it's move
  5692. number (or with grid coordinates for the 'curses' version of the program).
  5693. Note that there can be more than one game per file.
  5694. .H 3 "Playing/Existing Games"
  5695. Enter moves using mouse or keyboard, comments can also be typed in. Write the
  5696. file away, if the file had previously been read in then only the new moves and
  5697. comments are appended to the file providing the same filename is entered.
  5698. Possible to make practice moves by selecting "practice" on the menu, spacebar
  5699. will remove the practice stones, to make a 'real' move, the player needs to 
  5700. select "practice" again.
  5701. .H 2 "File Format"
  5702. Each line of the files read in and written away conform to one of the following
  5703. patterns. Note this is also the format for typing commands at the keyboard.
  5704. Each block shown in the diagrams can optionally be separated by white spaces (
  5705. ie spaces or tabs).
  5706. .P
  5707. The pipe
  5708. character '|' is used when stepping through a file, if it is present at the end
  5709. of a line then there is no pause waiting for the player to press space bar, the
  5710. program continues on to read the next line.
  5711. .H 3 "Configure"
  5712. .DS CB
  5713. .GS
  5714.                                                   @---@
  5715.     @--------@  @-------------@   @--------@      |   | 
  5716. ----| number |--| white space |-|-| number |-|-|--| | |--------|----
  5717.     @--------@  | or carriage | | @--------@ | |  |   |        |
  5718.                 | return      | |            | |  @---@        |
  5719.                 @-------------@ |------------| |               |
  5720.                                                |  @---------@  |
  5721.                                                |--| Comment |--|
  5722.                                                |  @---------@  |
  5723.                                                |               |
  5724.                                                |---------------|
  5725. .GE
  5726. .DE
  5727. .P
  5728. The first number is the size of the board, the second is the handicap. If
  5729. the second number is omited then then the handicap is assumed to be zero.
  5730. .H 3 "A Move"
  5731. .DS CB
  5732. .GS
  5733.                                      @---@
  5734.        @--------@  @--------@        |   | 
  5735. ----|--| letter |--| number |--|--|--| | |--------|----
  5736.     |  @--------@  @--------@  |  |  |   |        |
  5737.     |                          |  |  @---@        |
  5738.     |                          |  |               |
  5739.     |  @--------@              |  |  @---------@  |
  5740.     |--| "pass" |--------------|  |--| Comment |--|
  5741.        @--------@                 |  @---------@  |
  5742.                                   |               |
  5743.                                   |---------------|
  5744. .GE
  5745. .DE
  5746. One ascii letter 'a' to 't', no 'i' followed by a number represents the
  5747. coordinatesof a move. The string "pass" is used when a player decides there
  5748. are no moves he or she could sensibly make (when both players pass the game
  5749. is over)
  5750. .H 3 "Comment"
  5751. .DS CB
  5752. .GS
  5753.                                    @---@
  5754.       @---@   @--------------@     |   |
  5755. ------| # |---| ascii string |--|--| | |--|---
  5756.       @---@   @--------------@  |  |   |  |
  5757.                                 |  @---@  |
  5758.                                 |---------|
  5759. .GE
  5760. .DE
  5761. .H 3 "Control"
  5762. .DS CB
  5763. .GS
  5764.     @---@     @--------------@          @---------@
  5765. ----| ! |-----| control word |-----|----| Comment |----|----
  5766.     @---@     @--------------@     |    @---------@    |
  5767.                                    |                   |
  5768.                                    |-------------------|
  5769. .GE
  5770. .DE
  5771. .P
  5772. Possible values of the control word are:-
  5773. .VL 12 2
  5774. .LI "grid"
  5775. Toggles the displaying of the grid (coordinates around the board).
  5776. .LI "numbers"
  5777. Toggles the displaying of the numbers on the stones (only meaningful for 630s).
  5778. .LI "lastmove"
  5779. Toggles the displaying of the Last Move.
  5780. .LI "clear"
  5781. Erases the screen.
  5782. .LE
  5783. .H 2 "Features Explained"
  5784. This section explains the features available to the players.
  5785. .BL
  5786. .LI
  5787. \fIChange Directory\fR - The default directory can be passed as a parameter
  5788. to the program. Using the 'change directory' command  the player can change 
  5789. this string.
  5790. The directory string will be prepended to any filename entered.
  5791. .LI
  5792. \fIConfigure\fR - Configuring erases any current game in progress. The player
  5793. is prompted for the size and handicap of the new game. Handicaps are only
  5794. available on board sizes 9, 13 and 19 and handicaps higher than 5 are only
  5795. allowed on a size 19 board. CONFIGURING OVERWRITES THE PREVIOUS GAME IF NOT
  5796. STEPPING.
  5797. .P
  5798. Configuring may be accomplished via the keyboard or menu.
  5799. .LI
  5800. \fIControls\fR - Controls are ways the player can configure the internal
  5801. parameters of the program. In general they can be toggled on or off via
  5802. keyboard input, or in the case of 630 terminals via the menu.
  5803. .DL
  5804. .LI
  5805. \fIGrid\fR The grid is the axis coordinates displayed around the board.
  5806. .LI
  5807. \fINumbers\fR Display the numbers on the stones (630 terminals only)
  5808. .LI
  5809. \fILast Move\fR The last move is by default displayed, this control allows
  5810. it to be not displayed.
  5811. .LI
  5812. \fIClear\fR Erase the screen.
  5813. .LE
  5814. .LI
  5815. \fIGoto\fR - Goto is only a valid option if the stepping flag is on and practice
  5816. flag is off.
  5817. There are two types of goto :-
  5818. .DL
  5819. .LI
  5820. \fIGoto Move\fR Displayed on the menu is the current move number within  a game
  5821. , it is possible to goto any move within a game either by specifying the move
  5822. number or by it's grid coordinates if player is using the 'curses' version of
  5823. the program.
  5824. .LI
  5825. \fIGoto Line\fR Also displayed on the menu is the current line number within
  5826. the file the player is stepping through. It is possible to goto to any line
  5827. within the file.
  5828. .LE
  5829. .LI
  5830. \fIPass\fR - A player can 'pass' via the keyboard (or 630 menu).
  5831. .LI
  5832. \fIPractice\fR - This toggles the practice flag which is displayed on the menu.
  5833. Practicing enables the player
  5834. to try out combinations of moves before deciding on the actual play. Spacebar
  5835. clears the practice stones but play can only continue with the practice flag
  5836. off. During practice stones captured and 'lastmove' are not displayed.
  5837. .LI
  5838. \fIRead From\fR - After entering the filename the moves are displayed on the
  5839. screen while the whole file is read into memory. Further moves by the player(s)
  5840. are appended to this game.
  5841. .LI
  5842. \fIRedraw\fR - Clears the screen and redraws the board.
  5843. .LI
  5844. \fIStep Through\fR - When this is selected the player is prompted for a filename
  5845. to step through. To step through the file press the spacebar (or button 2 of the
  5846. mouse). The stepping flag is indicated on the menu.
  5847. .P
  5848. While stepping moves are not allowed to be entered unless the practice flag is
  5849. on.
  5850. To leave the stepping mode select "read from" or "configure".
  5851. .LI
  5852. \fIUndo\fR - It is possible to undo the last move made (even during practice
  5853. and stepping). Note that if comments were added after a move played the the undo
  5854. will also remove these.
  5855. .LI
  5856. \fIWrite To\fR - Writing files away is only possible if the stepping
  5857. flag is off.
  5858. If "write to" is selected after a file has been read in then the moves played
  5859. after the reading are appended to that existing file (if the filename for
  5860. writing is the same as the one entered for reading). In the other cases the whole
  5861. of the current game is written away.
  5862. .LE
  5863. .H 1 "PROGRAMMER REFERENCE"
  5864. .P
  5865. This section is for programmers who wish to write a terminal interface driver
  5866. for the program.
  5867. .H 2 "Building"
  5868. Here is a list of existing C files.
  5869. .VL 15
  5870. .LI "go.c"
  5871. This contains the 'core' functions of the program including main(). Also
  5872. declares the global variables needed in the terminal interface driver.
  5873. .LI "go.h"
  5874. Header file that defines types common to go.c and go.*.c
  5875. .LI "go.patch.h"
  5876. This header takes care of differences between 630 and 'curses' compilers.
  5877. .LI "go.interface.h"
  5878. Header file that declares the functions defined in the driver file.
  5879. .LI "go.extern.h"
  5880. Header file that contains the variables definitions declared in go.c. This is
  5881. included in go.*.c
  5882. .LI "go.curses.c"
  5883. Terminal interface driver for standard terminals.
  5884. .LI "go.630.c"
  5885. Terminal interface driver for 630 DMD terminals.
  5886. .LI "go.skeleton.c"
  5887. Skeleton of a terminal interface driver.
  5888. .LE
  5889. .P
  5890. To build for a standard terminal:-
  5891. .DS C
  5892. cc -o $GO/bin/go.out go.c go.curses.c -lcurses
  5893. .DE
  5894. .P
  5895. To build for a 630 terminal:-
  5896. .DS C
  5897. dmdcc -o $GO/bin/go.630.out go.c go.630.c
  5898. .DE
  5899. .P
  5900. Note that there is a shell script called 'c' that will perform the above
  5901. commands dependent on $TERM.
  5902. .P
  5903. To build for a new type of terminal make a copy of go.skeleton.c
  5904. (renaming the middle
  5905. portion to something that will indicate the terminal type) and edit it according
  5906. to the interface described in the section below. Also edit the 'go' shell script
  5907. to accommodate the new terminal type.
  5908. .H 2 "Terminal Interface"
  5909. .P
  5910. The following is a description of the functions that must be provided in the 
  5911. terminal interface driver.
  5912. .DS 
  5913. .B
  5914. void clearpromptline()
  5915. .R
  5916. .DE
  5917. .P
  5918. The promptline is the line that all player entry and comments are displayed on,
  5919. in the "curses" interface driver this function just scrolls the line up and in
  5920. the 630 version sets the text to be written one line lower that the last.
  5921. .DS 
  5922. .B
  5923. void displaycaptured()
  5924. .R
  5925. .DE
  5926. .P
  5927. Shows the number of black and white stones captured.
  5928. .DS 
  5929. .B
  5930. void displaylastmove(s)
  5931. char *s ;
  5932. .R
  5933. .DE
  5934. .P
  5935. Displays string s in the required format for last move (providing that the
  5936. lastmove flag is ON)
  5937. .DS 
  5938. .B
  5939. void displaystring(s)
  5940. char *s ;
  5941. .R
  5942. .DE
  5943. .P
  5944. Displays string s at the prompt line.
  5945. .DS 
  5946. .B
  5947. void drawempty(x,y)
  5948. COORD x,y ;
  5949. .R
  5950. .DE
  5951. .P
  5952. Draws an empty place on the board. If using bitmapped displays (eg 630) then
  5953. use postype() and starpoint() (defined in go.c) to determine if it is
  5954. necessasry to draw a small disc to indicate a star point.
  5955. .DS 
  5956. .B
  5957. void drawgrid()
  5958. .R
  5959. .DE
  5960. .P
  5961. Draws the coordinate references 'A' to 'T' along the top and 19 to 1 down the
  5962. left side.
  5963. .DS 
  5964. .B
  5965. void drawstone(x,y,n,c)
  5966. COORD x,y ;
  5967. MOVENUMBER n ;
  5968. COLOUR c ;
  5969. .R
  5970. .DE
  5971. .P
  5972. Draws a stone of the right colour at (x,y). If the terminal is a bitmapped display
  5973. draw any associated board lines and if the practice flag/number flag allow
  5974. print the number on the stone ( providing that (x,y) is not a star point, move
  5975. number is 2 and the handicap is non zero ). If practice flag is on and this is
  5976. a standard terminal then highlight the stone with bold (bit mapped displays in
  5977. this case do not print a number on the stone).
  5978. .DS 
  5979. .B
  5980. void endterminalspecific()
  5981. .R
  5982. .DE
  5983. .P
  5984. Allows the interface driver to perform any terminating graphics routines just
  5985. before exiting the program.
  5986. .DS 
  5987. .B
  5988. void erasescreen()
  5989. .R
  5990. .DE
  5991. .P
  5992. Clears the whole screen.
  5993. .DS
  5994. .B
  5995. void errorprint(s)
  5996. char *s ;
  5997. .R
  5998. .DE
  5999. .P
  6000. Displays string as an error to the player. This used to warn of an internal
  6001. error eg default hit in a switch, file unreadable or an error in the
  6002. file being read in.
  6003. .DS 
  6004. .B
  6005. void getdirectory(s)
  6006. char *s ;
  6007. .R
  6008. .DE
  6009. .P
  6010. Display "Enter directory :", then if global variable "directory" is not null
  6011. then display it. Allow the player to enter/edit the text using backspace
  6012. and delete (terminal interrupt) keys. The resultant string is copied into *s.
  6013. .DS 
  6014. .B
  6015. void getfilename()
  6016. .R
  6017. .DE
  6018. .P
  6019. Display "Enter filename :", then if global variable "filename" is not null
  6020. then display it. Allow the player to enter/edit a suitable string.
  6021. .DS 
  6022. .B
  6023. void getinput(action,actionbuffer)
  6024. ACTIONTYPE action ;
  6025. char actionbuffer[MAXLINELENGTH] ;
  6026. .R
  6027. .DE
  6028. .P
  6029. Sets action and actionbuffer (if necessary) according to mouse/keyboard input.
  6030. .DS 
  6031. .B
  6032. void reconfigure()
  6033. .R
  6034. .DE
  6035. .P
  6036. Lets the terminal interface driver know that the size/handicap has changed.
  6037. .DS 
  6038. .B
  6039. void refreshmenu()
  6040. .R
  6041. .DE
  6042. .P
  6043. The menu displays all the flags, current move and current line. This function
  6044. updates the menu with these values and if necessary displays them on the screen.
  6045. .DS 
  6046. .B
  6047. void startterminalspecific()
  6048. .R
  6049. .DE
  6050. .P
  6051. Terminal driver's opportunity to initialise data/screens etc. at the start of
  6052. running the program.
  6053. .H 1 "COMMAND LINE INVOCATION"
  6054. At the unix prompt the 'go' shell script can accept certain parameters :-
  6055. .DS CB
  6056. go [-c] [-d <directory>] [-r <filename>]
  6057. .DE
  6058. .VL 10 5
  6059. .LI "-c"
  6060. \fIFor 630 terminals only\fR Use this option to cache the program so that
  6061. the game can be run after quitting  without loading it up again. To remove it
  6062. from cache use the 630 tool 'ucache' which, using button 3, enables the player
  6063. to remove programs from the cache. Note that once a program is cached its
  6064. parameters cannot be changed at a later invocation.
  6065. .LI "-d"
  6066. The parameter after the -d is treated as the default directory which will
  6067. be prepended to any filename within the program.
  6068. .P
  6069. .DS I F 5
  6070. \fIIt is recommended that players set up an alias to use the -d facility so
  6071. that it will point to a directory where all the players' games are stored eg
  6072. alias go="go -d /d1/usr/go"
  6073. \fR
  6074. .DE
  6075. .LI "-r"
  6076. The parameter after the -r is treated as a filename to be read in (not stepped
  6077. through) at the start of the program.
  6078. .LE
  6079. .H 1 "OTHER FILES"
  6080. .P
  6081. The full list of files on release are as follows:-
  6082. .DS
  6083. .TS
  6084. box;
  6085. c|c
  6086. l|l.
  6087.     Description
  6088. =
  6089. basics.go    Intro. to the rules of go
  6090. bgj.75.go    Sample game from the British Go Journal Issue 75
  6091. c    Shell script to aid compilation
  6092. example.go    A complete introductory game with comments.
  6093. game1.go    Sample game played between R.Parker(13) and D.Bradley(2)
  6094. game2.go
  6095. game3.go
  6096. go    Shell script to run the program
  6097. go.630.c    Terminal interface driver for a 630 terminal
  6098. go.630.out    Executable for a 630
  6099. go.c    Core functions of the program
  6100. go.curses.c    Terminal interface driver for a standard terminal
  6101. go.curses.out    Executable for standard terminal.
  6102. go.extern.h    Definitions of external variables.
  6103. go.h    General header file
  6104. go.mmx    This doc.
  6105. go.skeleton.c    Skeleton for a terminal interface driver
  6106. go_icon    Icon used by 630 terminal
  6107. go.interface.h    Terminal interface driver function definitions
  6108. kobattle.go    Description of a ko battle
  6109. makefile    Used in compilation for standard terminals
  6110. null_icon    Icon used by 630 terminal
  6111. go.patch.h    Terminal specific patches
  6112. start.630.go    How to use the 630 version of the program.
  6113. start.go    How to use the standard version of program
  6114. tick_icon    Icon used by 630 terminal
  6115. .TE
  6116. .DE
  6117. .H 1 "FURTHER INFO"
  6118. For more information about go playing in the UK please contact the membership
  6119. secretary of the British Go Association:-
  6120. .DS
  6121.     Brian Timmins
  6122.     The Hollies
  6123.     Wollverton
  6124.     Market Drayton   TF9 3LY
  6125. .DE
  6126. .P
  6127. A good introductory book to Go is 'Go For Beginners' by Kaoru Iwamoto, published
  6128. by Penguin.
  6129. .H 1 "BUGS/ENHANCEMENTS NEEDED"
  6130. .AL
  6131. .LI
  6132. First black move on an empty handicap point will not have a number displayed on it (630 terminals)
  6133. .LI
  6134. Undo of practice stones taken off will not be marked in bold (standard terminals) or the number re-appears (630 terminals)
  6135. .LI
  6136. Terminal driver should prevent player from requesting certain operations
  6137. whilst in certain modes eg
  6138. .DL
  6139. .LI
  6140. "goto" should be prevented whilst not stepping
  6141. .LI
  6142. Adding comments should be prevented whilst stepping
  6143. .LI
  6144. Should not be able to change to stepping whilst in practice mode.
  6145. .LE
  6146. .LI
  6147. Should be some routines to automatically count points at the end of a game
  6148. .LI
  6149. If kill a comment using the 'delete' key, a blank line is still 
  6150. written away.
  6151. .LI
  6152. If capture a stone during practice (one of the first two played, non
  6153. practice)
  6154. and replace it with a practice stone of the same number then on 
  6155. stopping practice the stone will have no number.
  6156. .LI
  6157. Redraw during practice draws all stones in bold (or with no numbers)
  6158. .LI
  6159. Controls would be better if as well as toggling with '!controlword', you
  6160. could also set them eg '!controlword=on'
  6161. .LE
  6162. .TC
  6163. SHAR_EOF
  6164. fi
  6165. if test -f 'go.patch.h'
  6166. then
  6167.     echo shar: "will not over-write existing file 'go.patch.h'"
  6168. else
  6169. cat << \SHAR_EOF > 'go.patch.h'
  6170. /********************************************************************/
  6171. /* Put in here any terminal specific patches for the compilers sake */
  6172. /********************************************************************/
  6173.  
  6174. #ifdef dmd
  6175. #include <dmdio.h>
  6176.  
  6177. #define malloc alloc    /* The 630/5620 compiler has a diffrent function
  6178.              * name for allocating memory.
  6179.              */
  6180. #else
  6181. #include <stdio.h>
  6182. #endif
  6183.  
  6184. SHAR_EOF
  6185. fi
  6186. if test -f 'go.skeleton.c'
  6187. then
  6188.     echo shar: "will not over-write existing file 'go.skeleton.c'"
  6189. else
  6190. cat << \SHAR_EOF > 'go.skeleton.c'
  6191. #include "go.h"
  6192. #include "go.extern.h"
  6193.  
  6194. #define BACKSPACE 8
  6195. #define KILLLINE 127
  6196. /* this is carriage return on the keyboard ^M, ('\n' is ^J) */
  6197. #define RETURN 13
  6198.  
  6199.  
  6200. /*
  6201.  * Function:    errorprint()
  6202.  *        
  6203.  * Description:    Prints a string in error format
  6204.  *        
  6205.  *        
  6206.  *        
  6207.  * Globals affected:    none
  6208.  *            
  6209.  */
  6210. void
  6211. errorprint(s)
  6212. char *s ;
  6213. {
  6214. }
  6215.  
  6216. /*
  6217.  * Function:    displaylastmove
  6218.  *        
  6219.  * Description:    
  6220.  *        
  6221.  *        
  6222.  *        
  6223.  * Globals affected:    
  6224.  *            
  6225.  */
  6226. void
  6227. displaylastmove(str)
  6228. char str[] ;
  6229. {
  6230. }
  6231.  
  6232. /*
  6233.  * Function:    erasescreen()
  6234.  *        
  6235.  * Description:    Clear the whole screen
  6236.  *        
  6237.  *        
  6238.  *        
  6239.  * Globals affected:    none
  6240.  *            
  6241.  */
  6242. void
  6243. erasescreen()
  6244. {
  6245. }
  6246.  
  6247. /*
  6248.  * Function:    reconfigure()
  6249.  *        
  6250.  * Description:    Terminal specific code after a configure of the board
  6251.  *        
  6252.  *        
  6253.  *        
  6254.  * Globals affected:    none
  6255.  *            
  6256.  */
  6257. void
  6258. reconfigure()
  6259. {
  6260. }
  6261.  
  6262. /*
  6263.  * Function:    getinput()
  6264.  *        
  6265.  * Description:    Gets input from keyboard (or mouse)
  6266.  *        Sets action to be one of the following, with corresponding
  6267.  *        data in the buffer.
  6268.  *        Any strings returned in the buffer always end with a newline
  6269.  *        and a null.
  6270.  *
  6271.  *        action        actbuffer
  6272.  *        ------        ---------
  6273.  *        cd        null
  6274.  *        gotomove    decimal string "1" to "999" or a move eg "D3",
  6275.  *                ending with newline. Maximum of four bytes long,
  6276.  *                plus '\0'.
  6277.  *        gotoline    decimal string "1" to "999" ending with newline.
  6278.  *                Maximum of four bytes long, plus '\0'.
  6279.  *        changehandicap    first byte is size, second is handicap
  6280.  *        numbers        null
  6281.  *        pass        null
  6282.  *        practice    null
  6283.  *        quit        null
  6284.  *        rawkeyboard    string typed in from the keyboard
  6285.  *        readfrom    null
  6286.  *        redraw        null
  6287.  *        changesize    first byte indicates new size
  6288.  *        spacebar    null
  6289.  *        stoneplayed    x and y in the first two bytes
  6290.  *        stepthrough    null
  6291.  *        undo        null
  6292.  *        writeto        null
  6293.  *        
  6294.  *        This function handles the displaying of the menu (together
  6295.  *        with the associated flags). The current move must be
  6296.  *        displayed on the menu in a relevant place.
  6297.  *        
  6298.  * Globals affected:    none
  6299.  *            
  6300.  */
  6301. void
  6302. getinput ( action, actbuffer ) 
  6303. ACTIONTYPE *action ;
  6304. char       actbuffer[MAXLINELENGTH] ;
  6305. {
  6306. }
  6307.  
  6308. /*
  6309.  * Function:    drawgrid
  6310.  *        
  6311.  * Description:    Draws the 'A' to 'T' along the top and 19 to 1 down the side
  6312.  *        
  6313.  *        
  6314.  *        
  6315.  * Globals affected:    none
  6316.  *            
  6317.  */
  6318. void
  6319. drawgrid()
  6320. {
  6321. }
  6322.  
  6323. /*
  6324.  * Function:    drawempty
  6325.  *        
  6326.  * Description:    Draws an empty place on the board
  6327.  *        
  6328.  *        
  6329.  *        
  6330.  * Globals affected:    none
  6331.  *            
  6332.  */
  6333. void
  6334. drawempty(x,y)
  6335. COORD x,y ;
  6336. {
  6337. }
  6338.  
  6339. /*
  6340.  * Function:    drawstone
  6341.  *        
  6342.  * Description:    Draws a stone, with number if possible/allowed
  6343.  *        
  6344.  *        
  6345.  *        
  6346.  * Globals affected:    none
  6347.  *            
  6348.  */
  6349. void
  6350. drawstone(x,y,n,c)
  6351. COORD x,y ;
  6352. MOVENUMBER n ;
  6353. COLOUR c ;
  6354. {
  6355. }
  6356.  
  6357. /*
  6358.  * Function:    getdirectory
  6359.  *        
  6360.  * Description:    If directory is already set then copy directory into dn.
  6361.  *        Display dn, and allow editting of it with backspace and
  6362.  *        kill.
  6363.  *        
  6364.  * Globals affected:    
  6365.  *            
  6366.  */
  6367. void
  6368. getdirectory(dn)
  6369. char dn[] ;
  6370. {
  6371. }
  6372.  
  6373. /*
  6374.  * Function:    getfilename
  6375.  *        
  6376.  * Description:    If filename is already set then copy filename into fn.
  6377.  *        Display fn, and allow editting of it with backspace and
  6378.  *        kill.
  6379.  *        
  6380.  * Globals affected:    
  6381.  *            
  6382.  */
  6383. void
  6384. getfilename(fn)
  6385. char fn[] ;
  6386. {
  6387. }
  6388.  
  6389. /*
  6390.  * Function:    displaycaptured
  6391.  *        
  6392.  * Description:    
  6393.  *        
  6394.  *        
  6395.  *        
  6396.  * Globals affected:    
  6397.  *            
  6398.  */
  6399. void
  6400. displaycaptured()
  6401. {
  6402. }
  6403.  
  6404. /*
  6405.  * Function:    refreshmenu()
  6406.  *        
  6407.  * Description:    This function is called when some information on the menu
  6408.  *        has changed, the screen needs updating.
  6409.  *        
  6410.  *        
  6411.  * Globals affected:    none
  6412.  *            
  6413.  */
  6414. void
  6415. refreshmenu()
  6416. {
  6417. }
  6418.  
  6419. /*
  6420.  * Function:    clearpromptline
  6421.  *        
  6422.  * Description:     Clears the player input/comment display line.
  6423.  *        
  6424.  *        
  6425.  *        
  6426.  * Globals affected:    none
  6427.  *            
  6428.  */
  6429. void
  6430. clearpromptline()
  6431. {
  6432. }
  6433.  
  6434. /*
  6435.  * Function:    displaystring()
  6436.  *        
  6437.  * Description:    Displays a string in the promptline
  6438.  *        
  6439.  *        
  6440.  *        
  6441.  * Globals affected:    none
  6442.  *            
  6443.  */
  6444. void
  6445. displaystring(s)
  6446. char *s ;
  6447. {
  6448. }
  6449.  
  6450. /*
  6451.  * Function:    startterminalspecific
  6452.  *        
  6453.  * Description:    Graphics routines initialisation etc.
  6454.  *        
  6455.  *        
  6456.  *        
  6457.  * Globals affected:    none
  6458.  *            
  6459.  */
  6460. void
  6461. startterminalspecific(argc,argv)
  6462. int argc ;
  6463. char *argv[] ;
  6464. {
  6465. }
  6466.  
  6467. /*
  6468.  * Function:    endterminalspecific
  6469.  *        
  6470.  * Description:    Graphics routines termination before exit.
  6471.  *        
  6472.  *        
  6473.  *        
  6474.  * Globals affected:    none
  6475.  *            
  6476.  */
  6477. void
  6478. endterminalspecific()
  6479. {
  6480. }
  6481. SHAR_EOF
  6482. fi
  6483. if test -f 'go_icon'
  6484. then
  6485.     echo shar: "will not over-write existing file 'go_icon'"
  6486. else
  6487. cat << \SHAR_EOF > 'go_icon'
  6488. Texture16 go_icon = {
  6489.      0x0810, 0x0810, 0x3FFC, 0x0810,
  6490.      0x0FF0, 0x0810, 0x0FF0, 0x0810,
  6491.      0x3FFC, 0x0810, 0x0FD0, 0x1A18,
  6492.      0x37EC, 0x6C26, 0x0BE0, 0x0000,
  6493. };
  6494. SHAR_EOF
  6495. fi
  6496. if test -f 'makefile'
  6497. then
  6498.     echo shar: "will not over-write existing file 'makefile'"
  6499. else
  6500. cat << \SHAR_EOF > 'makefile'
  6501. $(GO)/bin/go.curses.out :    go.o go.curses.o
  6502.                 cc -o $(GO)/bin/go.curses.out go.o go.curses.o -lcurses 
  6503.  
  6504. #go.o depends on go.630.out because could have 
  6505. #done 'c' for the 630 which would give go.o a
  6506. #"bad magic number"
  6507. go.o : go.c go.h $(GO)/bin/go.630.out
  6508.     cc -c go.c
  6509.  
  6510. #go.o : go.c go.h 
  6511. #    cc -c go.c
  6512.  
  6513. go.curses.o : go.curses.c go.h
  6514.     cc -c go.curses.c
  6515. SHAR_EOF
  6516. fi
  6517. if test -f 'null_icon'
  6518. then
  6519.     echo shar: "will not over-write existing file 'null_icon'"
  6520. else
  6521. cat << \SHAR_EOF > 'null_icon'
  6522. Word null_icon[] = {
  6523.      0x0000, 0x0000, 0x0000, 0x0000,
  6524.      0x0000, 0x0000, 0x0000, 0x0000,
  6525.      0x0000, 0x0000, 0x0000, 0x0000,
  6526.      0x0000, 0x0000, 0x0000, 0x0000,
  6527. };
  6528. SHAR_EOF
  6529. fi
  6530. if test -f 'tick_icon'
  6531. then
  6532.     echo shar: "will not over-write existing file 'tick_icon'"
  6533. else
  6534. cat << \SHAR_EOF > 'tick_icon'
  6535. /* This is hand editted output of a Texture16 created with
  6536.  * the 'icon editor' program. Replace 'Texture16' with 'Word'
  6537.  * and put '[]' after 'tick_icon'.
  6538.  */
  6539. Word tick_icon[] = {
  6540.      0x0000, 0x0000, 0x0000, 0x0006,
  6541.      0x000E, 0x001C, 0x0038, 0x0070,
  6542.      0xC0E0, 0xE1C0, 0x7380, 0x3F00,
  6543.      0x1E00, 0x0C00, 0x0000, 0x0000,
  6544. };
  6545. SHAR_EOF
  6546. fi
  6547. cd ..
  6548. exit 0
  6549. #    End of shell archive
  6550.